Http 304 & Cache-Control: no-cache

8
我看到一些对Web服务器的调用产生了以下响应:

首次调用:

HTTP/1.1 200 OK
Date: Mon, 16 Jan 2012 05:46:49 GMT
X-Powered-By: Servlet/2.5 JSP/2.1
Content-Type: text/plain
Content-Length: 78
Content-Encoding: gzip
Etag: "pv2052dae8634d971149a927231e3ceddf"
Cache-Control: no-cache
X-PvInfo: [S10202.C6191.A6057.RA6008.G182D.U3FAE8760].[OT/plaintext.OG/documents]
Vary: Accept-Encoding
Set-Cookie: JSESSIONID=l9pLPT5J1tpgK19Fq2qlT0F15ryByWDLgVLz16ffWPm4qQp6nzzx!-518520380; path=/; HttpOnly
DST=rd319o00000000000000000000ffffac16018bo8200; path=/
Connection: close

后续调用:
HTTP/1.1 304 Not Modified
Date: Mon, 16 Jan 2012 05:48:43 GMT
Connection: close
Etag: "pv2052dae8634d971149a927231e3ceddf"
Cache-Control: no-cache
Vary: Accept-Encoding

我不明白的是,这两个调用都向浏览器返回了Cache-Control: no-cache指令。然而,第二个调用还返回了一个304 Not Modified
考虑到服务器已被告知不要缓存之前的响应,它希望页面从哪里获取数据呢?
有趣的是,我看到响应已在浏览器中缓存,尽管有no-cache指令。为什么?

请在第一次请求和后续请求中发布请求头。您将看到浏览器发送给Web服务器的内容。Cache-Control:no-cache表示Web服务器指示浏览器不缓存响应正文。 - rkosegi
1个回答

25

Cache-Control: no-cache 意味着响应不能直接使用客户端缓存,而是需要与服务器重新验证成功后才能使用:

如果no-cache指令没有指定字段名称,则缓存必须不使用响应来满足后续请求,除非与源服务器进行了成功的重新验证。这允许原始服务器防止即使是已配置为向客户端请求返回陈旧响应的缓存也进行缓存。

因此,客户端可以将响应存储在本地缓存中,但需要通过源服务器重新验证响应。如果服务器说客户端缓存中存储的响应仍然有效(即304响应),则客户端可以使用存储的响应来满足请求。


2
很好的解释。我该如何告诉服务器 返回 Cache-Control 指令?即我不希望客户端重新验证与服务器的连接? - Peter McEvoy
@PeterMcEvoy为某段时间设置了“cache-control: max-age”,或者如果您希望文件永远不会更改,可以使用“immutable”指令。 - Null
@PeterMcEvoy,浏览器重新验证是因为它收到了“ETag:...”和“Last-Modified:...”头文件。如果没有这些头文件,它将无法重新验证,而必须执行完整的“GET”。如果您控制客户端,请不要发送相应的头文件(“If-None-Match:...”和“If-Modified-Since:...”)。如果您控制服务器,请不要发送“ETag:...”和“Last-Modified:...”,或忽略传入的“If-...”(但如果您有CDN和其他中间缓存,则可能会很棘手)。 - Alexis Wilke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接