最新的Chomium和Google Canary上的Amazon S3的CORS问题

Chr*_*lli 16 google-chrome amazon-s3 amazon-web-services cors

我们的网站在使用最新版本的Chromium(版本33.0.1722.0 - 237596)和Chrome Canary在Amazon S3存储桶上加载CSS和JS资源时遇到问题.它适用于任何其他浏览器,包括当前的Chrome(31.0.1650.57).

错误是:

来自" https://mybucket.s3.amazonaws.com "的脚本已被跨源资源共享策略阻止加载:请求的资源上没有"Access-Control-Allow-Origin"标头.因此,不允许来源" https://app.example.com "访问.

我们在资源桶上的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>
        <MaxAgeSeconds>300000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>
Run Code Online (Sandbox Code Playgroud)

这是Chromium的错误吗?最新的CORS规格有什么变化吗?

dig*_*noe 14

亚马逊几个月后发布了针对此问题的解决方案.我们在当前版本的Chrome和Safari中看到了错误(没有检查Firefox).对于仍然遇到此问题的任何人,请尝试以下配置:

S3 bucket CORS策略:

<?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)

CloudFront分配设置("行为"选项卡):

  1. 允许的HTTP方法:GET,HEAD,OPTIONS
  2. 转发标头:白名单
  3. 白名单标题:Origin,Access-Control-Request-Headers,Access-Control-Request-Method

我们通过具有S3源的CloudFront托管css和静态javascript文件.我们通过引用我们的javascript文件 <script crossorigin="anonymous" src="http://assets.domain.com/app.js">.

编辑

我们开始使用Safari 10.1.2再次看到这个问题.事实证明我们以两种方式访问​​Javascript文件......

在页面A通过<script crossorigin="anonymous" src="http://assets.domain.com/app.js">.在页面B通过$.ajax()(所以它是懒惰加载).

如果你去了第A页 - >第B页 - >第A页,我们会得到一个交叉来源拒绝错误.我们采取了延迟加载方法,它解决了我们的问题(再次).


Rya*_*man 10

很有可能,您遇到了S3/CloudFront/CORS的一个众所周知的问题.我能找到的最佳解决方案是在S3和CloudFront之间安装一个代理应用程序,在返回时始终向对象添加适当的CORS头.

在将CORS资产提供给不同的Web浏览器时,S3 + CloudFront已经崩溃.问题是双重的.

  • 并非所有浏览器都需要CORS来处理Web字体和其他静态资源.如果其中一个浏览器发出请求,S3将不会发送CORS标头,CloudFront将缓存(无用的)响应.
  • CloudFront的不支持的Vary: Origin头,所以它有问题,使用*AllowedOrigin价值,只会缓存第一倍数AllowedOrigin值.

最后,这两个问题使得S3 + CloudFront成为使用CORS和(快速)CDN解决方案的难以为继的解决方案 - 至少是开箱即用的.防弹解决方案是创建一个简单的应用程序,代理S3和CloudFront的的要求,一直在增加必要的CORS标头,这样CloudFront的始终缓存他们.

请求"冷"缓存

  • ←浏览器从CloudFront请求静态资产.
  • ←CloudFront未命中,并命中其原始服务器(代理应用程序).
  • ←代理应用程序将请求传递给S3.
  • →S3响应代理应用程序.
  • →Proxy App添加正确的CORS标头(无论S3是否已发送).Proxy App响应CloudFront.
  • →CloudFront缓存结果并响应浏览器.

请求"热"缓存

  • ←浏览器从CloudFront请求静态资产.
  • →CloudFront命中,并响应浏览器.

是的,这是一个众所周知的广泛问题:

我可以说我们的S3和CloudFront团队非常清楚这里讨论的问题.通过编写一个可以充当S3和CloudFront之间代理的简单应用程序,您可以在CloudFront缓存它们之前手动注入所有正确的CORS响应标头.

如果您始终在Firefox中工作,那么您可能不会注意到该问题 - CloudFront将始终缓存您启用CORS的响应.如果您主要在Safari或Chrome中工作,当您切换回需要这些标题的浏览器(Firefox和IE)时,您会更频繁地看到它.此外,如果您有单独的开发/暂存/生产环境,则可能会更频繁地遇到多源问题.


nas*_*san 8

将任何查询参数添加?cacheblock=true到url中,如下所示:

而不是:https://somebucket.s3.amazonaws.com/someresource.pdf

执行:https://somebucket.s3.amazonaws.com/someresource.pdf?cacheblock = true

技术解释我没有完全失望.但它类似于以下内容:

包含查询参数将阻止Chrome中的"行为不当"缓存行为,从而导致Chrome发出预检请求和实际请求的新请求,从而允许两个请求都出现正确的标头,从而允许S3正确响应.大约.


小智 6

想要用一个替代的理论来解决这个老问题:Chrome 至少自2014年8月以来就存在一个错误/“功能”,如果首次通过正常提取来加载资源,则该错误会导致跨域请求失败因为Chrome会缓存少用CORS的资源标头,然后拒绝将缓存的资源提供给跨域请求。

更糟的是,在复杂的场景中进行测试时,刷新之间(由于资源加载的顺序?)甚至不一定完全一致,并且其他浏览器似乎没有共享行为。

这是有趣的错误搜寻!看来,简单地将其添加crossorigin='anonymous'到加载资源的所有标签中,就会迫使Chrome引入CORS标头,从而修复了后续的跨域请求。