首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何让seadragon js与亚马逊网络服务S3预签网址一起工作

如何让seadragon js与亚马逊网络服务S3预签网址一起工作
EN

Stack Overflow用户
提问于 2021-03-11 04:50:10
回答 1查看 102关注 0票数 1

我正在尝试让openseadragon js来处理存储在我的AWS S3存储桶中的图像。这些文件是私有的,我不确定如何引用包含我所有金字塔图像的文件夹。在tilesource自定义documentation中,他们使用:

代码语言:javascript
复制
OpenSeadragon({
    id:            "example-custom-tilesource",
    prefixUrl:     "/openseadragon/images/",
    navigatorSizeRatio: 0.25,
    wrapHorizontal:     true,
    tileSources:   {
        height: 512*256,
        width:  512*256,
        tileSize: 256,
        minLevel: 8,
        getTileUrl: function( level, x, y ){
            return "http://s3.amazonaws.com/com.modestmaps.bluemarble/" +
                    (level-8) + "-r" + y + "-c" + x + ".jpg";
        }
    }
});

我不确定getTileUrl中的函数(level,x,y)是如何工作的。我假设它会迭代到某个点。任何关于它是如何工作的解释都会很有帮助。因此,基于这个例子,我尝试了以下方法:

代码语言:javascript
复制
const s3 = new AWS.S3();

const s3_bucket_url_js = function($key) {

    s3.getSignedUrl('getObject', {
            Bucket: "g-deliverables",
            Expires: 60*30,
            Key: $key,
    }, function (err, url) {
        if (err) {
         console.log(err);
     } else {
         console.log(typeof url);
         return url;

     }

    });
}


OpenSeadragon({
    id:            "openseadragon1",
    prefixUrl:     "/GTSS/assets/buttons",
        showNavigator: false,
    tileSources:   {
        type: 'zoomifytileservice',
        height: 3600,
        width:  2700,
        tileSize: 256,
            getTileUrl: function( level, x, y ){
            var url_s = "whatever/pyr/some#/01_VISUAL/TileGroup0/" +level + "-" + x + "-" + y + ".jpg";
            return s3_bucket_url_js(url_s);
        }
    }
});

我使用了适用于JS的AWS sdk版本2。我创建了一个以存储桶键为参数的函数,然后将这个名为s3_bucket_url_js的函数放入getTileUrl函数(level,x,y)中。因为我不知道函数(level,x,y)是如何工作的,所以我假设它迭代到最小级别,所以我让它创建了我的jpg文件名,它遵循三位数的命名约定: 0-0-0.jpg,1-0-0.jpg,1-1-0.jpg,等等。我想把这个完整的键值放到我的s3_bucket_url函数中,以创建一个预签名的url,我希望它能成功呈现。当然,它没有。

我在s3存储桶中的文件夹结构如下:

folder structure s3 bucket

当我将文件存储在ec2上时,我只是简单地引用了tilesUrl:'gtss/pyr/103/01_VISUAL/,而不是getTileUrl,它在编译所有图像时都工作得很好,但我无法引用s3存储桶上的文件夹,因为它是私有的。

最后,在html中,我为要显示的openseadragon映射添加了div标记。

代码语言:javascript
复制
<div id="openseadragon1" style="width: 800px; height: 600px;"></div>

快速更新:我已经查看了我正在使用的openseadragon.min.js文件,并且相信我找到了返回每个金字塔图像的路径的函数getTileUrl。具体如下:

代码语言:javascript
复制
    _calculateAbsoluteTileNumber: function(e, t, i) {
            var n = 0;
            var o = {};
            for (var r = 0; r < e; r++) n += (o = this.gridSize[r]).x * o.y;
            return n += (o = this.gridSize[e]).x * i + t
        },
        supports: function(e, t) {
            return e.type && "zoomifytileservice" == e.type
        },
        configure: function(e, t) {
            return e
        },
        getTileUrl: function(e, t, i) {
            var n;
            var o = this._calculateAbsoluteTileNumber(e, t, i);
            n = Math.floor(o / 256);
            return this.tilesUrl + "TileGroup" + n + "/" + e + "-" + t + "-" + i + ".jpg"
        }

现在,我正在考虑尝试在getTileUrl方法中使用s3_bucket_url_js函数并返回s3_bucket_url_js(this.tilesUrl + "TileGroup“+ n+ "/”+e+ "-“+t+ "-”+i+ ".jpg“

之前有一个关于从后端调用预签名的url并将其传递给前端的评论。我该如何在openseadragon.min.js文件中使用s3_bucket_url_js()呢?

这是代码片段的非精简版本:

代码语言:javascript
复制
  //private
        _calculateAbsoluteTileNumber: function(level, x, y) {
            var num = 0;
            var size = {};

            //Sum up all tiles below the level we want the number of tiles
            for (var z = 0; z < level; z++) {
                size = this.gridSize[z];
                num += size.x * size.y;
            }
            //Add the tiles of the level
            size = this.gridSize[level];
            num += size.x * y + x;
            return num;
        },

        /**
         * Determine if the data and/or url imply the image service is supported by
         * this tile source.
         * @function
         * @param {Object|Array} data
         * @param {String} optional - url
         */
        supports: function(data, url) {
            return (data.type && "zoomifytileservice" == data.type);
        },

        /**
         *
         * @function
         * @param {Object} data - the raw configuration
         * @param {String} url - the url the data was retrieved from if any.
         * @return {Object} options - A dictionary of keyword arguments sufficient
         *      to configure this tile sources constructor.
         */
        configure: function(data, url) {
            return data;
        },

        /**
         * @function
         * @param {Number} level
         * @param {Number} x
         * @param {Number} y
         */
        getTileUrl: function(level, x, y) {
            //console.log(level);
            var result = 0;
            var num = this._calculateAbsoluteTileNumber(level, x, y);
            result = Math.floor(num / 256);
            return this.tilesUrl + 'TileGroup' + result + '/' + level + '-' + x + '-' + y + '.jpg';

        }

EN

回答 1

Stack Overflow用户

发布于 2021-03-27 07:24:39

到目前为止,我们已经知道了如何通过js浏览器输出s3预签名的url。我们使用aws cognito身份池id代替aws密钥,以允许我们在浏览器中使用aws sdk js。通过修改我们使用的openseadragon.min.js文件,我们能够为图片添加预签名的urls。在5370行附近有一个getTileUrl函数,它编译缩放金字塔的文件夹路径:

代码语言:javascript
复制
  getTileUrl: function(e, t, i) {
        var n;
        var o = this._calculateAbsoluteTileNumber(e, t, i);
        n = Math.floor(o / 256);
        var url = this.tilesUrl + "TileGroup" + n + "/" + e + "-" + t + "-" + i + ".jpg";
        return s3_bucket_url_js(url);


    }

在最后一条语句中,我们在函数中放置了一个return (位于我们放置map div的同一文件中),它返回一个能够编译的预签名url。如果您注意到var、url = this.titleUrl等,则可以在OpenSeadragon()对象中找到this.tilesUrl:

代码语言:javascript
复制
var viewer = OpenSeadragon({
                  id:            "openseadragon1",
                  prefixUrl:     "assets/buttons/",
                  showNavigator: false,
tileSources:   {
          type: 'zoomifytileservice',
          height: 3600,
          width:  3600,
          tileSize: 256,
          tilesUrl: 'whatever/pyr/our path up to TileGroup#/'});

下面是我们使用的s3函数(还请注意,我们在浏览器中使用了aws sdk版本2)。至少对我们来说,异步调用s3.getSignedUrl()不起作用,所以我们必须使用同步方式,如下所示:

代码语言:javascript
复制
   AWS.config.region = 'us-east-1';
   AWS.config.credentials = new AWS.CognitoIdentityCredentials({IdentityPoolId: 'your own identity pool' });
   const s3 = new AWS.S3();
   function s3_bucket_url_js(key) {
       var params = {Bucket: 'bucket name', Key: key, Expires:1000};
       var s3_presigned = s3.getSignedUrl('getObject', params);
       return s3_presigned;
       }

另请注意,身份池供未经身份验证的用户使用。我们向附加到身份池的角色添加了s3只读访问IAM策略。在我们关闭的s3存储桶中,我们添加了CORS策略:

代码语言:javascript
复制
[
{
    "AllowedHeaders": [
        "*"
    ],
    "AllowedMethods": [
        "GET"
    ],
    "AllowedOrigins": [
        "your site"
    ],
    "ExposeHeaders": [
        "Content-Type",
        "X-Amz-Date",
        "Authorization",
        "X-Api-Key",
        "X-Amz-Security-Token"
    ]
}

]

现在,我们在编译方面遇到了一些问题。使用我们的密钥,OpenSeaDragon成功地编译了所有图像,但是使用身份池Id,金字塔的前两层没有编译和返回https://s3.amazonaws.com/的非预签名url,chrome发送了CORB错误(可能是因为url不是图像)。我相信这与浏览器发送的对Identity Pool Id的请求有关,但我们仍在努力解决此问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66572645

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档