没有任何Cache-Control标头的浏览器缓存请求/响应

时间:2020-07-10 16:38:52

标签: http-headers http-caching request-headers

我在SPA Web应用程序和REST API后端遇到浏览器缓存问题。我可以在打开开发人员工具的情况下在Firefox和Safari上重现它:我确保未禁用缓存。

当我第一次进入仅从REST API获取并显示对象的特定页面时,我会使用“硬刷新”(在Mac上为CMD + R)来实现。我看到以下标题:

第一个请求:

Host: localhost:5000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:77.0) Gecko/20100101 Firefox/77.0
Accept: application/json, text/plain, */*
Accept-Language: en,it;q=0.7,fr;q=0.3
Accept-Encoding: gzip, deflate, br
Origin: http://localhost:3000
DNT: 1
Connection: keep-alive
Referer: http://localhost:3000/literature/sde5e-zeb98
Cookie: ...
If-Modified-Since: Fri, 10 Jul 2020 16:19:24 GMT
If-None-Match: "2"
Cache-Control: max-age=0

(请注意Cache-Control标头,由于硬刷新而自动添加)

响应:

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 6128
ETag: "2"
Last-Modified: Fri, 10 Jul 2020 16:19:24 GMT
Link: <https://localhost:5000/api/documents/sde5e-zeb98>; rel="self"
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 52
X-RateLimit-Reset: 1594398279
Retry-After: 60
X-Frame-Options: sameorigin
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31556926; includeSubDomains
Referrer-Policy: strict-origin-when-cross-origin
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Expose-Headers: Content-Type, ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
Access-Control-Allow-Credentials: true
Vary: Origin
Server: Werkzeug/1.0.1 Python/3.6.7
Date: Fri, 10 Jul 2020 16:23:38 GMT

请求已按预期到达后端,我正在记录它。后端返回ETag + Last modified头,但不返回其他缓存头(例如max-age)。我希望浏览器始终访问后端。

当我没有进行强制刷新,而只是简单地在网站上导航到另一个页面,然后再次导航到该页面(不是通过后退按钮)时,就会发生此问题,这基本上是网站的正常使用情况。 我希望浏览器每次都向后端执行请求,后端返回ETag和200/304状态代码,并且浏览器相应地使用客户端缓存(后端的ETag计算是正确的)。 问题在于请求甚至没有到达后端,没有执行请求,没有命中后端,我也不明白为什么。我可以在Firefox的cached列中看到值Transferred

提出请求:

Host: localhost:5000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:77.0) Gecko/20100101 Firefox/77.0
Accept: application/json, text/plain, */*
Accept-Language: en,it;q=0.7,fr;q=0.3
Accept-Encoding: gzip, deflate, br
Origin: http://localhost:3000
DNT: 1
Connection: keep-alive
Referer: http://localhost:3000/literature/sde5e-zeb98
Cookie: ...

(没有Cache-Control标头,是正确的,应该是正常行为)

缓存的响应(没有后端命中):

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 6128
ETag: "2"
Last-Modified: Fri, 10 Jul 2020 16:19:24 GMT
Link: <https://localhost:5000/api/documents/sde5e-zeb98>; rel="self"
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 52
X-RateLimit-Reset: 1594398445
Retry-After: 60
X-Frame-Options: sameorigin
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31556926; includeSubDomains
Referrer-Policy: strict-origin-when-cross-origin
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Expose-Headers: Content-Type, ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
Access-Control-Allow-Credentials: true
Vary: Origin
Server: Werkzeug/1.0.1 Python/3.6.7
Date: Fri, 10 Jul 2020 16:26:24 GMT

我试图了解哪个标头正在阻止浏览器执行请求。我没有设置Cache-Control标头。 我怀疑Vary标头可能有问题,但任何提示都值得赞赏。

有什么主意如何调试浏览器为什么要缓存请求?什么标题错误?谢谢!

1 个答案:

答案 0 :(得分:3)

缺少Cache-ControlExpires并不意味着缓存被禁用;这意味着浏览器可以自由实施自己的缓存策略。如RFC 7234中所述:

由于原始服务器并不总是提供明确的到期时间, 当明确的时间时,缓存可以分配启发式到期时间 未指定,使用使用其他标头字段的算法 值(例如Last-Modified时间)来估计合理的值 到期时间。

您实际想要的caching policyCache-Control: no-cache,请返回。

响应可能由 any 缓存存储,即使该响应通常是不可缓存的。但是,存储的响应必须在使用前始终先经过原始服务器的验证。