我创建了一个测试存储桶,启用了 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:标头(这意味着“如果您改变您的请求中的以下标头之一,我的响应可能会有所不同。”)我所指的上述输出中的标头是这些。
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 添加到对象的 URL 的常见浏览器缓存破坏策略.如果做不到这一点,您应该考虑使用curl 之类的工具来证明或反驳您的存储桶的正确行为,该工具可以准确显示请求/响应中发生的情况。