为什么浏览器仍然使用max-age发送缓存控制公共请求?

时间:2013-09-01 09:55:32

标签: google-chrome amazon-s3 http-headers amazon-cloudfront cache-control

我有Amazon S3对象,对于每个对象,我都设置了

Cache-Control: public, max-age=3600000

大约是41天。

我的Amazon CloudFront Distribution设置了最小TTL,也有3600000。

这是清除缓存后的第一个请求。

GET /1.0.8/web-atoms.js HTTP/1.1
Host: d3bhjcyci8s9i2.cloudfront.net
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8

响应是

HTTP/1.1 200 OK
Content-Type: application/x-javascript
Content-Length: 226802
Connection: keep-alive
Date: Wed, 28 Aug 2013 10:37:38 GMT
Cache-Control: public, max-age=3600000
Last-Modified: Wed, 28 Aug 2013 10:36:42 GMT
ETag: "124752e0d85461a16e76fbdef2e84fb9"
Accept-Ranges: bytes
Server: AmazonS3
Age: 342557
Via: 1.0 6eb330235ca3971f6142a5f789cbc988.cloudfront.net (CloudFront)
X-Cache: Hit from cloudfront
X-Amz-Cf-Id: 92Q2uDA4KizhPk4TludKpwP6Q6uEaKRV0ls9P_TIr11c8GQpTuSfhw==

即使亚马逊明确发送了Cache-Control,Chrome仍然会发出第二个请求,而不是从缓存中读取它。

GET /1.0.8/web-atoms.js HTTP/1.1
Host: d3bhjcyci8s9i2.cloudfront.net
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
If-None-Match: "124752e0d85461a16e76fbdef2e84fb9"
If-Modified-Since: Wed, 28 Aug 2013 10:36:42 GMT

问题: 为什么chrome会提出第二次请求?

到期 当我在标头中放置显式Expires属性时,此行为会更改。浏览器不会发送后续的Expires标头请求,但对于缓存控制公共,它会发送它。我的所有S3对象永远不会改变,它们是不可变的,当我们更改文件时,我们将它们作为带有新URL的新对象。

在页面脚本参考中 Chrome有时会发出后续请求,我通过在浏览器中实际输入网址来进行此测试。当HTML页面引用脚本时,对于很少的后续请求,chrome会加载缓存的脚本,但是在某个时间之后,它会在一段时间内向服务器发送请求。此处没有磁盘大小问题,Chrome有足够的缓存空间。

问题是我们对每个请求收费,并且我希望S3对象永远缓存,并且应该从Cache加载,并且永远不应该连接到服务器。

5 个答案:

答案 0 :(得分:37)

当您在Chrome中按 F5 时,它将始终向服务器发送请求。这些将使用Cache-Control:no-cache标头进行。服务器通常会响应304(未更改)状态代码。

Ctrl + F5 Shift + F5 时,会执行相同的请求,但是console/config/main.php标头,因此强制服务器发送未缓存的版本,通常带有200(OK)状态代码。

如果您想确保自己使用本地浏览器缓存,只需在地址栏中按 Enter 即可。

答案 1 :(得分:19)

如果HTTP响应包含etag条目,则将始终进行条件请求。 ETag是缓存验证程序标记。客户端将始终将etag发送到服务器以查看元素是否已被修改。

答案 2 :(得分:9)

如果Chrome开发者工具已打开(F12),Chrome通常会停用缓存。

它可以在开发人员工具设置中控制 - 开发工具顶部栏右侧的齿轮图标。

答案 3 :(得分:0)

如果您点击刷新按钮以加载特定页面或资源,则每次都会发送if-modified-since标头请求,如果您在新标签页或链接中请求将页面/资源作为单独的请求在脚本或html页面中,它将从浏览器缓存本身加载页面/资源。

这就是我的情况,也许这是一般的普遍情况。我不完全确定,但这是我通过挖掘收集到的。

答案 4 :(得分:0)

当您使用自签名证书时,Chrome 会添加 Cache-control: max-age=0 标头。从 HTTPS 切换到 HTTP 将删除此标头。

Firefox 不添加此标头。