【问题标题】:AWS Cors Issue - Node.jsAWS Cors 问题 - Node.js
【发布时间】:2016-04-15 04:01:19
【问题描述】:

我目前在请求使用 CORS 标头存储在 AWS S3(简单存储)上的图像时遇到问题。我已经在 AWS 控制台上设置了 CORS 配置 - 设置如下:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

但是,在请求我存储的这些图像时,我得到的响应有点到处都是,而且断断续续。有时图像会返回所需的标题,有时则不是。我真的不确定为什么会这样。当我尝试对页面上的 Access-Control-Allow-Origin 标头设置为 * 的图像发出多个请求时,效果似乎会恶化(例如,如果我需要检索 10 个图像,所有图像都带有跨源标头)。

这些是我需要的标题:

Access-Control-Allow-Methods:GET
Access-Control-Allow-Origin:*
Access-Control-Max-Age:3000

我真的不确定我做错了什么。我已经确保每个图像标签也添加了 crossOrigin="anonymous" 属性,但同样没有运气。

我需要这些图像跨源工作的原因是因为我安装了一个角度插件,它允许用户裁剪图像并将图像的裁剪版本存储为 base64 字符串。但是,尝试检索它们时出现以下错误。

这些是正确返回的图像的标题:

Request URL:https://trajansmarket.s3.amazonaws.com/be5bbda0-b04a-11e5-81d3-dd7ff3efeebc.jpg
Request Method:GET
Status Code:304 Not Modified
Remote Address:54.231.252.131:443

Response Headers
view source
Access-Control-Allow-Methods:GET
Access-Control-Allow-Origin:*
Access-Control-Max-Age:3000
Cache-Control:public, max-age=31536000
Date:Tue, 12 Jan 2016 21:13:03 GMT
ETag:"77bdbe9b517acc8cba86024c592bce3f"
Last-Modified:Fri, 01 Jan 2016 05:46:21 GMT
Server:AmazonS3
Vary:Origin, Access-Control-Request-Headers, Access-Control-Request-Method
x-amz-id-2:F3OQpOHsAqySk9LNwwoJXVATVIByr4Gtvz953ZoL7DdB/dtE9nYwo99R59Rj6RzZc3dcHyk6wWY=
x-amz-request-id:CD220FF1F6EE6CA9

Request Headers
view source
Accept:image/webp,image/*,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6,ms;q=0.4
Connection:keep-alive
Host:trajansmarket.s3.amazonaws.com
If-None-Match:"77bdbe9b517acc8cba86024c592bce3f"
Origin:http://91.121.220.161:3000
Referer:http://91.121.220.161:3000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36

这是一个没有标题的:

Request URL:https://trajansmarket.s3.amazonaws.com/c0671e00-b04a-11e5-81d3-
dd7ff3efeebc.jpg
Request Method:GET
Status Code:200 OK (from cache)
Remote Address:54.231.252.135:443

Response Headers
Accept-Ranges:bytes
Cache-Control:public, max-age=31536000
Content-Length:142102
Content-Type:application/octet-stream
Date:Tue, 12 Jan 2016 00:35:36 GMT
ETag:"beb93f56e3a2a65b983addd8af35c26c"
Last-Modified:Fri, 01 Jan 2016 05:46:25 GMT
Server:AmazonS3
x-amz-id-2:5XvaOd8bxMr5zwK317DfDMbk2+kzu3Zd7rsf2xl0hxwI40Oc4KDnQpgzD3sgtCRm9SXGqa93Mh0=
x-amz-request-id:FD3EB1978C38013B

Request Headers
Provisional headers are shown
Accept:image/webp,image/*,*/*;q=0.8
Origin:http://91.121.220.161:3000
Referer:http://91.121.220.161:3000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36
X-DevTools-Emulate-Network-Conditions-Client-Id:498F45FE-5D49-4AE0-AF58-F81B9AFD48AF

我只是想知道是否有人知道为什么会发生这种情况。任何帮助将不胜感激。

【问题讨论】:

  • 在您的浏览器开发者工具网络选项卡中,您能否确认您收到了所需的 cors 标头
  • 您好,它是间歇性的。有时我会收到带有标题的图像,有时在刷新后我没有。几乎就像 CORS 规则由于某种原因不能与 AWS 一起正常工作。有什么想法吗?
  • 所以,您并不总是收到 CORS 标头 - 似乎是 AWS 的问题
  • 我也是这么想的。看起来我将不得不与他们的支持团队聊天以尝试解决它,这意味着我可能必须升级计划:(
  • 缓存的响应能否消除对预检请求的需要,或者缓存的响应可能会丢失一些标头?

标签: javascript angularjs node.js amazon-s3


【解决方案1】:

这非常令人沮丧,我仍然没有弄清楚 AWS S3 间歇性返回 CORS 所需的标头的原因。

从那以后,我想到了一种解决方法,即从亚马逊“下载”并将我需要的图像存储在本地文件夹中 - 允许用户“裁剪”图像并将其存储,然后再从本地删除这些图像文件夹。

为了将图像文件流式传输到本地文件夹,我在 s3 的 .getObject 方法上使用了 fs.createWriteStream 方法。可以在以下位置找到一个示例:enter link description here

这消除了我实际请求带有 CORS 标头的图像的需要,因为当它们存储在本地时,不再需要标头。然后我可以保存我的cropper 指令生成的base64 并将其轻松存储在亚马逊S3 上。

如果用户在裁剪本地图像之前离开,我会从本地文件夹中删除它们,以免被阻塞。

我希望这对那些也遇到 CORS 标头问题的人有所帮助 - 即使这只是一种解决方法。

【讨论】:

    【解决方案2】:

    嗯,我已经以多种不同的形式看到了这个问题: 一种是您在 S3 中提供访问 EC2 或 Elastic Beanstalk 中的 nodejs 后端的页面。

    在一种情况下,是我使用 IE10 的浏览器引发了错误,因为浏览器需要设置 Preflight 选项。

    在其他情况下,我在 Elastic Beanstalk 中使用 Restify,在 S3 中使用 Angular。我在请求中添加了 Restify-cors 中间件包:

    var corsMiddleWare = require('restify-cors-middleware'); //npm install this package
    var cors = corsMiddleWare ({
        allowHeaders:['Authorization', 'API-Token', 'API-Token-Expiry']
     });
    server.pre(cors.preflight);
    server.use(cors.actual);
    //rest of server definition
    

    这似乎奏效了。 在 express 的情况下,有 node 包 express-cors:

    var cors = require('cors');
    app.use(cors());
    

    无论哪种情况,关键是所有请求都必须正确设置标头,因此我们将它们添加到中间件。 (应用程序/服务器。使用) How can I support cors when using restify

    您使用的是香草节点吗?在这种情况下,您需要在向 s3 发出的每个请求中添加标头。

    【讨论】:

      【解决方案3】:

      这对我来说绝对是一个缓存响应的问题。它似乎丢失了缓存中的一些标头。通过将随机时间参数附加到图像名称,我能够让它在 100% 的时间内工作,如下例所示。

      img = new Image();
      img.src = "https://s3.amazonaws.com/bucket/img.png?t=" + (new Date().getTime() / 1000);    
      img.crossOrigin = "Anonymous";
      

      【讨论】:

        猜你喜欢
        • 2019-06-04
        • 1970-01-01
        • 2018-01-13
        • 2021-09-04
        • 1970-01-01
        • 2018-08-21
        • 1970-01-01
        • 2016-06-27
        • 2018-06-16
        相关资源
        最近更新 更多