【问题标题】:S3 not returning Access-Control-Allow-Origin headers?S3 不返回 Access-Control-Allow-Origin 标头?
【发布时间】:2013-07-08 08:25:18
【问题描述】:

我无法强制 S3 在它从存储桶返回的所有对象上设置 CORS 标头,尽管启用了 CORS,因为客户端 S3 上传工作正常,返回的对象没有 CORS 标头!

我启用的策略是:

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

示例对象 URL https://s3.amazonaws.com/captionable/meme/test

有谁知道怎么回事?

【问题讨论】:

    标签: amazon-s3 cors


    【解决方案1】:

    首先,确保每个请求都有一个Origin 标头。如果没有发送 Origin 标头,S3 将不会发送 access-control 标头,因为 S3 认为它们无关紧要(通常情况下确实如此)。当通过 XMLHTTPRequest 进行跨域 HTTP 请求时,浏览器(使用 CORS 机制)会自动发送 Origin 标头。

    如果加载带有img的图片,你需要添加crossorigin="anonymous"属性。看 MDN Documentation on crossorigin attribute。这将导致浏览器发送Origin 请求标头,就像使用 XMLHTTPRequest 一样。

    按照 Sam Selikoff 的回答,您可能需要更改

     <AllowedOrigin>http://*</AllowedOrigin>
    

     <AllowedOrigin>http://*</AllowedOrigin>
     <AllowedOrigin>https://*</AllowedOrigin>
    

    我还没有测试过。

    按照 Paul Draper 对此答案的评论:注意缓存问题。浏览器可能使用不包含适当的Access-Control 响应标头的缓存响应。在开发过程中,您可以清除缓存。在生产环境中,如果之前以静态方式使用过资源,则必须切换到新的 URL。

    【讨论】:

    • 问题就在这里。我正在创建一个不发送 Origin 标头的图像标签。也就是说,我希望 S3 始终返回 CORS 标头,尽管它仅在指定“Origin”时才这样做。感谢您确认 CORS 已正确配置。
    • 我对该属性没有任何经验。将其设置为“匿名”可能只会触发浏览器发送Origin 标头。也许发布单独的问题?
    • 另外,请求必须是 GET 而不是 HEAD。用 curl 测试这个:curl -iH "Origin: test" http://…
    • 这个答案大部分是正确的,但肯定不是无关紧要的。如果缓存了没有 CORS 的响应,则下一个请求将检索一个无 CORS 的响应并失败。
    • 添加 &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"&gt; &lt;CORSRule&gt; &lt;AllowedOrigin&gt;*&lt;/AllowedOrigin&gt; &lt;AllowedMethod&gt;GET&lt;/AllowedMethod&gt; &lt;MaxAgeSeconds&gt;3000&lt;/MaxAgeSeconds&gt; &lt;AllowedHeader&gt;Authorization&lt;/AllowedHeader&gt; &lt;/CORSRule&gt; &lt;/CORSConfiguration&gt; 对我有用。但这仅在我打开开发人员控制台并转到网络选项卡并检查“禁用缓存”时才有效。不打开开发者控制台就不行。
    【解决方案2】:

    我也遇到了 &lt;image&gt; 标签,在遵循 Myrne Stol 的回答后,我将 crossorigin=anonymous 标签添加到我的图像标签中。我确认 Origin 标头确实被发送到 S3,但仍然没有发送 Access-Control-Allow-Origin 标头作为响应。

    我遇到了this SO answer,它解决了它。我将 S3 配置中的 AllowedOrigin 更改为:

    <AllowedOrigin>http://*</AllowedOrigin>
    <AllowedOrigin>https://*</AllowedOrigin>
    

    现在 S3 使用访问标头进行响应。耶!

    【讨论】:

    • @cory-dolphin 我认为这应该是这里公认的答案。我也对图像标签有同样的问题,添加这两行修复了它。
    • 这对我不起作用(大约 2 年后)。我已经更改了配置,并且正在使用 Postman 和
    • 您还必须在任何请求中包含一个 Origin 标头 - 这让我使用 curl(例如 curl -X GET -v --header "Origin: https://www.example.com" https://s3-eu-west-1.amazonaws.com/my-bucket/asset.ext
    【解决方案3】:

    Chrome 有一个他们无法修复的惊人错误:

    如果您有幸能够控制生成标签的代码,您可以将crossorigin="anonymous" 添加到标签中。
    喜欢&lt;img src="foo.bar/baz.jpg" crossorigin="anonymous" /&gt;
    如果您可以修改标记的 URL 或 XHR 请求的 URL,则可以向其中之一添加查询参数以绕过缓存。
    喜欢foo.bar/baz.jpg?x-request=xhr

    顺便说一句,Safari 也有这个问题。

    【讨论】:

    • NGL 我一直在努力寻找小时的解释,这应该得到更多的支持,因为这是我遇到问题的真正原因 - 我从没想过有 (或者在我的情况下甚至是 css 中的 background-image )会改变之后使用的 JS 代码的行为。你是救世主。
    • 我认为真正的问题是服务器会根据是否包含原始标头来改变响应,但响应中不包含“Vary: Origin”。因此,缓存完全有权返回没有 CORS 标头的响应,因为服务器允许缓存它。我假设我们在这里谈论的服务器是 S3 - 我正在发布一个错误报告,要求他们修复他们的错误行为。 fetch 规范有一个明确的描述 S3 违反:fetch.spec.whatwg.org/#cors-protocol-and-http-caches
    【解决方案4】:

    TLDR;确保请求(某处)需要 CORS 的资源的每个图像或视频元素都使用 crossorigin="anonymous"

    我在导出到画布的视频元素时遇到了这个问题。在 S3 中正确设置了 CORS,但它仍然给我一个错误并拒绝播放视频。

    原来有第二个视频元素指向同一个资源,而那个视频元素没有crossorigin="anonymous"。因此,第二个视频播放正常,因为它没有预期 access-control 标头,但服务器响应被缓存并阻止第一个视频播放,因为缓存的服务器响应没有 access-control header

    【讨论】:

      猜你喜欢
      • 2016-07-21
      • 2018-07-27
      • 2016-01-11
      • 2016-08-21
      • 2021-03-17
      • 2019-06-19
      • 2019-03-31
      相关资源
      最近更新 更多