当请求中的Origin标头存在时,AWS S3不发送Access-Control-Allow-Origin标头

时间:2016-05-27 14:21:18

标签: ajax amazon-web-services amazon-s3 cors

我有一个AWS 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>
        <AllowedHeader>*</AllowedHeader>
        <ExposeHeader>Access-Control-Allow-Origin</ExposeHeader>
    </CORSRule>
</CORSConfiguration>

在我的应用中,我从存储桶中加载了一页图像。图像按预期显示在页面上。当我单击其中一个图像以在Adobe Creative SDK中打开它时,SDK无法加载图像,因为它被CORS阻止。 SDK获取图像的URL并通过AJAX加载它。 SDK有一个启用CORS的选项,似乎正在发送正确的Origin标题(参见屏幕截图),但是AWS不包含Access-Control-Allow-Origin-Header,导致图像被CORS阻止。

我已经在这里搜索了关于这个主题的每一个问题,似乎没有人有一个正确的答案。关于这个问题有很多问题没有答案,但在许多情况下,似乎AJAX请求没有发送Origin标头或者没有正确配置存储桶。在这种情况下,这些都不是真的,这就是为什么这不是重复的

正如您在屏幕截图中看到的,该请求包含Origin标头,但响应中不包含Access-Control-Allow-Origin标头。我想知道的是:  1.如果我的存储桶配置正确,为什么S3没有发送正确的标头?  2.当Adobe Creative SDK通过AJAX请求图像时,浏览器是否可能看到图像已经缓存并尝试提供缓存的图像(没有Origin标题)?  3.如果是#2,我怎样才能强制将Origin标题添加到图像请求中?在应用程序中,图像是div的背景(css background-image属性)。

enter image description here

1 个答案:

答案 0 :(得分:2)

我创建了一个测试存储桶,启用了CORS,并使用了您的CORS规则。

请注意,我不相信<ExposeHeader>Access-Control-Allow-Origin</ExposeHeader>是必要的,但不应该因为在场而造成任何伤害,所以我保留了它。

我在测试时观察到的行为与您在浏览器的请求/响应标头中显示的内容不一致

使用curl,我将Origin:标头设置为http://example.com。 (是的,这实际上是我设置的......在下面的输出中没有修改过。)

$ curl -v http://xxxxxxxxxxxx.s3.amazonaws.com/index.txt -H 'Origin: http://example.com'
* Hostname was NOT found in DNS cache
*   Trying 54.231.98.120...
* Connected to xxxxxxxxxxxx.s3.amazonaws.com (54.231.98.120) port 80 (#0)
> GET /index.txt HTTP/1.1
> User-Agent: curl/7.35.0
> Host: xxxxxxxxxxxx
> Accept: */*
> Origin: http://example.com
>
< HTTP/1.1 200 OK
< x-amz-id-2: pF39K26ii42SzxSU2Dt0KT2z7+xmfyiP4yekp9s4DCYJo0jlRwCTDg6QO6f0HMIL4H9b640zq7U=
< x-amz-request-id: 3B18A563CFF4E485
< Date: Sat, 28 May 2016 21:49:21 GMT
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET
< Access-Control-Expose-Headers: Access-Control-Allow-Origin
< Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
< Cache-Control: no-cache
< Last-Modified: Sat, 28 May 2016 21:40:57 GMT
< ETag: "cd21a8c7268dc6af728d180f9a3a81d7"
< Accept-Ranges: bytes
< Content-Type: text/plain
< Content-Length: 71
* Server AmazonS3 is not blacklisted
< Server: AmazonS3

为什么这很有意思?

S3,配置了CORS并且<CORSRule>与您的请求相匹配,始终会返回CORS响应标头一个Vary:标头(这意味着&#34;如果您在请求中更改了以下标题之一,我可能会对我的回复有所不同。&#34;)我所指的上述输出的标题就是这些。

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Access-Control-Expose-Headers: Access-Control-Allow-Origin
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method

我可以找到一个例外,即没有匹配的CORS规则。为了证明这一点,我首先将我的CORS配置更改为<AllowedOrigin>http://example.com</AllowedOrigin>,然后重复请求。请注意,响应几乎相同,只是S3使用响应中的确切原点,并添加Access-Control-Allow-Credentials

< Access-Control-Allow-Origin: http://example.com
< Access-Control-Allow-Methods: GET
< Access-Control-Expose-Headers: Access-Control-Allow-Origin
< Access-Control-Allow-Credentials: true
< Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method

...但是,如果我 - 仍然使用指定特定来源的限制性更强的CORS规则 - 则发送Origin: example.org的请求,这是我的CORS配置中未提及的原点,没有要匹配的通配符<AllowedOrigin>,S3会响应,就好像根本没有配置CORS一样。

< HTTP/1.1 200 OK
< x-amz-id-2: WJ0QmIZ6jTQYefFi8GjlDQkZKFHDX8/5cmejeulhG1ov3/NdoSXbsTKetYpxvXPML8aUnPNZ/ac=
< x-amz-request-id: 15A03D8B1E08A830
< Date: Sat, 28 May 2016 21:58:34 GMT
< Cache-Control: no-cache
...etc.

这让我回到我的初步结论,即您显示浏览器的请求与您为CORS配置存储桶的时间不匹配,并且可能已经在您的存储桶的CORS之前进行了缓存设置处于正确状态,或者在匹配您在问题中发布的设置之前。

如果该请求中存在Origin:标头,如浏览器显示的那样,则S3应该添加了CORS响应标头,无论该请求是否实际上是跨源请求。

接下来的步骤是在新路径上尝试使用新对象,不可能进行缓存,或者尝试将?some-random=thing-here添加到对象的常见浏览器缓存清除策略&#39;发出请求时的URL。如果不这样做,您应该考虑使用像curl这样的工具来证明或反驳您的存储桶的正确行为,该工具可以准确显示请求/响应中发生的情况。