HTTP Cache-Control header 仅适用于本地主机

HTTP Cache-Control header works only on localhost

我正在尝试使用 Cache-Control 为我的 web 应用程序中的 REST 端点配置缓存,它在本地工作,但是当我在我们的生产服务器上部署时,浏览器不会缓存响应。

通过参数化的 ajax 请求查询端点(如下所示)。

一些相关说明:

本地主机

Request URL: http://localhost:8080/webapp/rest/events?_=1525720266960&start=2018-04-29&end=2018-06-10
Request Method: GET
Status Code: 200 OK
Referrer Policy: no-referrer-when-downgrade

=== Request ===
Accept: application/json, text/javascript, */*; q=0.01
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: JSESSIONID=<token>
Host: localhost:8080
Referer: http://localhost:8080/webapp/
X-Requested-With: XMLHttpRequest

=== Response ===
Cache-Control: no-transform, max-age=300, private
Connection: keep-alive
Content-Length: 5935
Content-Type: application/json

以下请求(针对相同参数)有效地从缓存中加载,唯一的区别是:Status Code: 200 OK (from disk cache)

这看起来不错,因为我不想重新验证。一旦资源在 Cache-Control.

指定的 max-age 的持续时间后变得陈旧,就应该再次获取资源,而无需验证

生产

Request URL: https://www.example.org/webapp/rest/events?_=1525720216575&start=2018-04-29&end=2018-06-10
Request Method: GET
Status Code: 200 OK
Referrer Policy: no-referrer-when-downgrade

=== Request ===
Accept: application/json, text/javascript, */*; q=0.01
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: JSESSIONID=<token>
Host: www.example.org
Referer: https://www.example.org/webapp/
X-Requested-With: XMLHttpRequest

=== Response ===
Cache-Control: no-transform, max-age=300, private
Connection: close
Content-Length: 5935
Content-Type: application/json

在这种情况下,之后永远不会从缓存中加载响应。


我删除了一些我认为多余的 headers (Server, X-Powered-By, User-Agent, Date)。

问题

是什么阻止了与生产服务器通信时浏览器缓存响应?

2 天后我再次尝试,缓存工作正常。 (我发誓我没疯)

相同的请求,相同的 headers,相同的响应。

我怀疑它属于某种覆盖响应的启发式 Cache-Control

这当然与这个端点之前没有指定 Cache-Control 的事实有关,所以浏览器忽略了 header 因为启发式倾向于重新获取而不是缓存,所以它不能去谨慎一点是错误的。

RFC2616

13.2.2 Heuristic Expiration

Since origin servers do not always provide explicit expiration times, HTTP caches typically assign heuristic expiration times, employing algorithms that use other header values (such as the Last-Modified time) to estimate a plausible expiration time. The HTTP/1.1 specification does not provide specific algorithms, but does impose worst-case constraints on their results. Since heuristic expiration times might compromise semantic transparency, they ought to used cautiously, and we encourage origin servers to provide explicit expiration times as much as possible.

总而言之,这是我得到的最好的解释。