Rob*_*yon 14 javascript safari amazon-s3 amazon-cloudfront
尝试从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>
Run Code Online (Sandbox Code Playgroud)
2.链接的CloudFront分配
以下标题已列入白名单(在行为下):
Access-Control-Request-HeadersAccess-Control-Request-MethodOrigin3. JavaScript
var img = new Image();
img.crossOrigin = '';
img.onload = function() {
console.log('image loaded');
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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';Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>Run Code Online (Sandbox Code Playgroud)
双重检查您的云端行为设置.您是否添加了自定义标题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是否存在响应.在云端行为设置中,有一个"转发查询字符串"的配置.这可能是一个因素.
在我的设置中,我有一个中间清漆缓存,所以我不得不弄乱它,以确保所有标头通过.看起来不像你有,但这是值得注意的.
小智 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
| 归档时间: |
|
| 查看次数: |
10190 次 |
| 最近记录: |