HTTP Cache-Control header 仅适用于本地主机
HTTP Cache-Control header works only on localhost
我正在尝试使用 Cache-Control
为我的 web 应用程序中的 REST 端点配置缓存,它在本地工作,但是当我在我们的生产服务器上部署时,浏览器不会缓存响应。
通过参数化的 ajax 请求查询端点(如下所示)。
一些相关说明:
我使用了一个 cache buster 参数 (_
),它是在页面加载时生成的 unix 时间戳。它不会在 ajax 个请求中改变。
本地主机在 HTTP 上,而生产环境在 HTTPS 上。证书有效,没有相关错误。
Firefox 59.0.2 和 Chrome66.0.3359.139 都表现出这种行为,所以我认为这是配置中的某些东西。
本地主机
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.
总而言之,这是我得到的最好的解释。
我正在尝试使用 Cache-Control
为我的 web 应用程序中的 REST 端点配置缓存,它在本地工作,但是当我在我们的生产服务器上部署时,浏览器不会缓存响应。
通过参数化的 ajax 请求查询端点(如下所示)。
一些相关说明:
我使用了一个 cache buster 参数 (
_
),它是在页面加载时生成的 unix 时间戳。它不会在 ajax 个请求中改变。本地主机在 HTTP 上,而生产环境在 HTTPS 上。证书有效,没有相关错误。
Firefox 59.0.2 和 Chrome66.0.3359.139 都表现出这种行为,所以我认为这是配置中的某些东西。
本地主机
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.
总而言之,这是我得到的最好的解释。