尝试从Safari 8中的CloudFront URL加载图像时出现以下错误:
Cross-origin image load denied by Cross-Origin Resource Sharing policy.
这只发生在Safari 8上。在FireFox 38和Chrome 41最新版中,它加载得很好。 (Mac 10.10)
1。具有以下CORS配置的S3存储桶
<?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>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
2。链接的CloudFront分配
以下标题已列入白名单(在行为下):
Access-Control-Request-Headers
Access-Control-Request-Method
Origin
第3。的JavaScript
var img = new Image();
img.crossOrigin = '';
img.onload = function() {
console.log('image loaded');
}
1。检查curl返回的标题
图片返回正确的标题(特别是Access-Control-Allow-Origin
)
> curl -sI -H 'Origin: localhost' -H 'Access-Control-Request-Method: GET' http://foo.cloudfront.com/image.jpg
...
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Server: AmazonS3
Vary: Origin,Access-Control-Request-Headers,Access-Control-Request-Method
X-Cache: Hit from cloudfront
<德尔>的 2。检查浏览器中返回的标题
有趣的是,图片并没有在所有三个浏览器中返回 Access-Control-Allow-Origin: *
标头。为什么会出现这种情况?
第3。将查询字符串添加到URL
向正在加载的URL添加查询字符串(例如?foo)会导致在浏览器中返回Access-Control-Allow-Origin
标题,并允许在Safari中加载图像!这很好,但为什么添加查询字符串允许它工作(并返回Access-Control-Allow-Origin
标题)?
4。从S3存储桶加载图像(未绑定到CloudFront分配)
从另一个与CloudFront无关的存储桶(具有相同的CORS配置)加载图像在Safari中也可以正常工作。
最初让我相信这是一个特别是CloudFront问题,但上面的查询字符串让我想到了。
这让我完全沮丧。任何人都可以帮助阐明上述内容吗?
感谢您的回复。令人沮丧的是,我似乎无法复制这个问题。
下面是一个片段,它可以加载两个图像(一个来自S3存储桶,另一个来自其各自的Cloudfront发行版),它们似乎也可以加载到你所期望的标题中,与我所说的相反上面的第2点。
不幸的是,我并没有真正接近一个明确的答案,但是现在我只是想把它归结为我的错误,可能会在我的CORS设置之前请求一张图片,如Derek建议的那样。
var img, imgCloudfront;
img = new Image();
img.crossOrigin = '';
img.onload = function() {
$('body').append('image loaded<br>');
}
img.src = 'http://sandbox-robinpyon.s3.amazonaws.com/test.jpg';
imgCloudfront = new Image();
imgCloudfront.crossOrigin = '';
imgCloudfront.onload = function() {
$('body').append('image (cloudfront) loaded<br>');
}
imgCloudfront.src = 'http://d32d4njimxij7s.cloudfront.net/test.jpg';
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
&#13;
答案 0 :(得分:7)
仔细检查您的云端行为设置。您是否添加了自定义标头Origin
。它应该是Access-Control-Allow-Origin
。我最近也设置了cloudfront,发现这篇文章很有帮助:http://kennethjiang.blogspot.com/2014/07/set-up-cors-in-cloudfront-for-custom.html
我在清除云端缓存方面遇到了问题。如果您在CORS设置之前请求了图像,那么Cloudfront可能会返回之前的图像,因此您的新配置不会被反映出来。您可以尝试运行失效,它是云端行为标签之一。我得到了不一致的结果。如果您想确保它正常工作,请上传新图片并进行测试。我使用rails并且偶尔会提升资产版本,这会导致我的所有资产都有新的指纹并解决了缓存问题,因为每个文件都有一个新名称。)
关于查询字符串的问题。您可能从云端获得了缓存缺失。您可以尝试使用curl重复练习,以查看响应X-Cache: Hit from cloudfront
是否存在。在云端行为设置中,有一个“转发查询字符串”的配置。这可能是一个因素。
在我的设置中,我有一个中间清漆缓存,所以我不得不弄乱它,以确保所有标头通过。看起来你没有这个但是需要注意的事项。
答案 1 :(得分:5)
请参阅:https://stackoverflow.com/a/13147554/1994767
Access-Control-Allow-Headers(<AllowedHeader>*</AllowedHeader>
)标头不允许使用通配符。它必须完全匹配:http://www.w3.org/TR/cors/#access-control-allow-headers-response-header
答案 2 :(得分:3)
这只是猜测,但缺少的Access-Control-Allow-Origin
标题似乎是我的关键点。出于某些原因,其他浏览器可以不使用它而不是Safari
您是否尝试过修改CloudFront配置?像转发所有标头而不是白名单,或更改查询字符串转发设置。正如其他人所说,请提供一个测试网址,以便我们自行检查。
答案 3 :(得分:2)
尝试清理浏览器缓存。
如果这不起作用,请提供示例图片的URL。
答案 4 :(得分:1)
我猜这与浏览器缓存有关。
S3存在一个问题,即S3省略了非CORS请求的“Vary:Origin”标头。这导致一些浏览器缓存非CORS响应并在后续需要CORS的请求中重用此缓存响应,从而导致浏览器抛出“跨源资源共享策略拒绝的跨源映像加载”。错误。
有关详细信息,请参阅:S3 CORS, always send Vary: Origin
也报告了这个问题