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

Aka*_*ava 37 google-chrome cache-control amazon-s3 http-headers amazon-cloudfront

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

Cache-Control: public, max-age=3600000
Run Code Online (Sandbox Code Playgroud)

那大概是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
Run Code Online (Sandbox Code Playgroud)

而响应是

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==
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

Der*_*ler 38

当您F5在Chrome中按时,它将始终向服务器发送请求.这些将通过Cache-Control:max-age=0标题进行.服务器通常会响应304(未更改)状态代码.

当您按Ctrl+ F5Shift+时F5,会执行相同的请求,但会使用Cache-Control:no-cache标头,从而强制服务器发送未缓存的版本,通常使用200(OK)状态代码.

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


woo*_*roo 21

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

  • 在我的测试中,Etags没有发挥作用(我的所有资源都有etag).我很确定这是你用Chrome测试的方式.在地址栏上按"enter"是测试缓存的最佳方法.F5或点击重新加载并发送"max-age = 0"标题.另见:http://stackoverflow.com/a/16510707/789658 (38认同)
  • 在Chrome版本57.0.2987.133(64位)中,即使来自云端的响应具有Cache-Control,在URL上按Enter键似乎仍然在请求中发送条件请求和max-age = 0:max-age = 300.基本上,无论我如何发出请求,我似乎都无法从浏览器的缓存中获取它.我已经验证了Dev Tools中没有禁用浏览器缓存.有任何想法吗?这是一张图片.我想知道Content-Type是否与它有关. (4认同)
  • 2件事:1.当直接在Chrome选项卡中浏览CloudFront中我的图像的URL时,我可以从浏览器缓存中可靠地获取它的唯一方法是通过Back/Forward获取URL.如果我在F5或按Enter键输入URL,我总是看到带有304的条件请求.2.直接转到图像URL时才会出现这种情况.当在HTML文档的内容中使用时,缓存按上述方式工作,其中F5刷新并在URL中按Enter键会产生不同的结果.只能假设Chrome正在考虑直接导航到URL,作为它应该执行条件请求的标志.预期? (4认同)
  • 截至此日期,Costa的回复仍然相关:如果刷新页面,Chrome会在请求标头中发送max-age = 0.如果您在URL中按Enter键,则不会. (3认同)
  • 如果有一个http**响应**那么请求已经发生并且忽略了'max-age`. (2认同)
  • @Bradley 评论仍然有效,节省了我很多时间!F5 或直接从 URL 导航器加载资源,chrome 发送 Cache-Control: max-age=0。当在应用程序中请求资源时,资源是从缓存中提供的。 (2认同)

小智 9

如果Chrome开发者工具处于打开状态(F12),则Chrome通常会禁用缓存.

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

  • 当我在框中打勾以禁用缓存时,F12仅禁用缓存,当我测试缓存时我确定启用了缓存. (6认同)