避免对HTTP响应进行缓存

30

如何避免HTTP数据缓存?我们可以同时修改客户端和服务器-因此我认为我们可以在客户端和服务器之间分配任务。

客户端可以在每个请求末尾添加一个随机参数http://URL/path?rand=6372637263——我的感觉是仅使用这种方式不能百分之百地解决问题,可能会有一些智能代理能够检测到该参数...另一方面,如果URL与先前的不同,则代理无法简单地决定返回某些缓存的响应。

服务器上可以控制一系列HTTP头:

Expires: Tue, 03 Jul 2001 06:00:00 GMT
Last-Modified: {now} GMT
Cache-Control: no-store, no-cache, must-revalidate, max-age=0
Cache-Control: post-check=0, pre-check=0
Pragma: no-cache

对于这个问题,有什么最佳方法的评论吗?

3个回答

52

服务器端缓存控制头应该如下所示:

Expires: Tue, 03 Jul 2001 06:00:00 GMT
Last-Modified: {now} GMT
Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate
避免在客户端重写 URL,因为这会污染缓存并导致其他奇怪的语义问题。此外:
  • 使用一个 Cache-Control 标头(参见rfc 2616),因为多个条目的行为是未定义的。而且第二个 cache-control 中的 MSIE 特定条目是最好是冗余的

  • no-store 是关于数据安全的。 (它只意味着不将此内容写入磁盘 - 缓存仍然可以将响应存储在内存中)。

  • Pragma: no-cache 在服务器响应中是没有意义的 - 它是一个请求标头,意味着接收请求的任何缓存都必须将其转发到源。

  • 同时使用 Expires (http/1.0)cache-control (http/1.1) 不是冗余的,因为存在仅支持 HTTP/1.0 的代理或将协议降级的代理。

  • 从技术上讲,在 no-cache 的情况下,最后修改的标头是冗余的,但最好将其保留。

  • 某些浏览器会在遇到不能识别的指令后忽略缓存控制标头中的后续指令 - 因此请优先放置重要内容。


2
我注意到人们仍然在查看这个答案。像互联网上的所有事物一样,它有点过时 - pushstate 确实允许客户端对 URL 进行微调 - 但要极度小心!也可以看看 mod_pagespeed。它处理了很多服务器上的 URL 重写和内容合并。除此之外,我的回答中其他内容仍然适用。 - symcbean
能否解释一下 Expires:Tue,03 Jul 2001 06:00:00 GMT - 这应该是 Expires:Thu,01 Jan 1970 00:00:00 GMT 吗? - lf215
1
@If215:在过去的任何时间应该防止缓存。然而,当你开始与许多计算机交流时,你会发现有些人的电池电量不足,时区配置错误和其他奇怪的问题。 - symcbean
注意:虽然这是一件好事,但GET请求仍然可以被代理缓存,使用它们自己的规则。也就是说,他们不会尊重你的头信息。永远不会。 - Rahly
根据规范,代理继承了浏览器缓存所受到的相同缓存义务。此外,还有一些指令专门针对中间缓存的行为(如规范中描述的缓存代理)。虽然并非所有设备都符合规则,但您的陈述是不准确且具有误导性的。 - symcbean

5

酷炫的演示。谢谢你分享。 - STeN
这并不完全正确。根据我的经验,Akamai CDN倾向于忽略此项设置,并且仍然会愉快地为您缓存私人数据。 - KrekkieD

0

要禁用缓存,您应该使用

Expires: 0 

或者

Cache-Control: no-store

如果你使用其中一个,就不应该使用另一个。


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