无法通过 Cloudfront 从 EC2 解码 CORS 压缩内容
Posted
技术标签:
【中文标题】无法通过 Cloudfront 从 EC2 解码 CORS 压缩内容【英文标题】:Unable to decode CORS gzipped content from EC2 via Cloudfront 【发布时间】:2015-07-16 23:47:11 【问题描述】:这可能与Serving gzipped CSS and javascript from Amazon CloudFront via S3 有关,但是尽管我遵循了文档,但我仍然可以解决这种情况:
一个 S3 存储桶包含我已 gzip 压缩的文件(使用 grunt-contrib-compress,如果有任何相关性。)
我的存储桶有一个 CORS 配置:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*.myorigin.net</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
存储桶通过 Cloudfront 提供服务。
我的 Cloudfront 已将 CORS 配置为:
允许 GET、HEAD、OPTIONS、PUT 等... 在 HTTPS 上 缓存 OPTIONS 请求 将 Access-Control-Request-Headers、Access-Control-Request-Method 和 Origin 列入白名单使用 curl,我可以获得我的资源,带有正确的标头来请求 gzip,我得到一个 gzip 压缩版本
curl --insecure https:/whatever.cloudfront.net/.../foo.js --silent -H "Accept-Encoding:gzip,deflate,sdch" -I
HTTP/1.1 200 OK
Content-Type: application/javascript
Content-Length: 33990
Connection: keep-alive
Date: Wed, 06 May 2015 17:12:53 GMT
Content-Encoding: gzip
Last-Modified: Wed, 06 May 2015 16:36:40 GMT
ETag: "7a92919df6117827de9474851afe06c0"
Accept-Ranges: bytes
Server: AmazonS3
Age: 70
X-Cache: Hit from cloudfront
Via: 1.1 (redacted).cloudfront.net (CloudFront)
X-Amz-Cf-Id: iaghGGDg3f3l4njz7mpXeOzqIS5OCR5kaehk4Td4-Bxiv2KtljHVlQ==
我可以通过添加--compressed
标志来解码内容,因此文件似乎是正确的。
如果我现在再次使用 curl 执行 CORS 请求,我会得到正确的编码:
curl --insecure https://.../foo.js --silent -H "Accept-Encoding: gzip,deflate,sdch" -I -H "Origin: myorigin.net"
HTTP/1.1 200 OK
Content-Type: application/javascript
Content-Length: 33990
Connection: keep-alive
Date: Wed, 06 May 2015 17:16:06 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, HEAD
Access-Control-Max-Age: 3000
Content-Encoding: gzip
Last-Modified: Wed, 06 May 2015 16:36:40 GMT
ETag: "7a92919df6117827de9474851afe06c0"
Accept-Ranges: bytes
Server: AmazonS3
Vary: Origin,Access-Control-Request-Headers,Access-Control-Request-Method
X-Cache: Miss from cloudfront
Via: 1.1 redacted.cloudfront.net (CloudFront)
X-Amz-Cf-Id: kaUV4S9wiCGzXp8N_Gg2LhGK8uYw1-qRtSw6w_Ry4V8oHZiLRvWULA==
由于某种原因,当我的 浏览器 发出请求时...没有“内容编码”,因此内容没有解压缩,因为我正在加载它requirejs,我得到一个严重的错误。
Request :
GET /resources-gz/foo.js HTTP/1.1
Host: d28p9e2ugw1o8w.cloudfront.net
Connection: keep-alive
Cache-Control: no-cache
Accept: */*
Pragma: no-cache
User-Agent: Mozilla/5.0 (X11; Linux i686 (x86_64)) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/35.0.1916.153 Safari/537.36
Referer: http://localhost:3000/start
Accept-Encoding: gzip,deflate,sdch
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,de;q=0.2
Response:
HTTP/1.1 200 OK
Content-Type: application/javascript
Content-Length: 33990
Connection: keep-alive
Date: Wed, 06 May 2015 16:31:27 GMT
Last-Modified: Wed, 06 May 2015 14:36:32 GMT
ETag: "7a92919df6117827de9474851afe06c0"
Accept-Ranges: bytes
Server: AmazonS3
Age: 1261
X-Cache: Hit from cloudfront
Via: 1.1 eazeaze.cloudfront.net (CloudFront)
X-Amz-Cf-Id: IjpNd37e-c38Moz3HQJ940KNTXfp1NN7O4enQJUYPd6Aet5Egw8XPg==
我显然错过了什么......
【问题讨论】:
【参考方案1】:是的,你错过了一些东西。
读取最后一个响应的响应头。
Last-Modified: Wed, 06 May 2015 14:36:32 GMT
ETag: "7a92919df6117827de9474851afe06c0"
Age: 1261
X-Cache: Hit from cloudfront
这是 CloudFront 缓存命中,CloudFront 在您请求之前 20 多分钟从 S3 获取此对象...并且此版本的对象最后一次在 S3 中修改是两个多小时前...所以,您正在获得一份可能可以追溯到您“修复”您最近修复的任何内容之前的副本。
当一个对象的 etag 没有改变时,这意味着 body 没有改变......但这并不意味着响应头的任何内容。
对此进行测试的最简单方法是在 S3 中放入一个您以前从未使用过的名称的新文件...当然是 gzip,然后再次尝试下载。
【讨论】:
那么为什么curl
完成的请求会缓存未命中,并接收到正确的标头,而浏览器完成的请求却是“旧”版本?另外,我启动了缓存的云端失效,它似乎没有帮助......谢谢!
当您从浏览器加载Age:
值时它会增加吗?如果不是,浏览器会假装从 CloudFront 获取它,但实际上是从它自己的本地浏览器缓存中加载它。
好吧,实际上,我想我已经解决了我的缓存失效问题(并且没有等待足够长的时间。)从一个干净的状态返回后,事情似乎还不错。所以这就是我所缺少的:耐心;)!!以上是关于无法通过 Cloudfront 从 EC2 解码 CORS 压缩内容的主要内容,如果未能解决你的问题,请参考以下文章
CloudFront + EC2 + Apache + PHP
EC2 上用于 Wordpress 的 Cloudfront