你目前正处于脱机状态,正在等待 Internet 重新连接

HOWTO:防止在 Internet Explorer 中进行缓存

概要
本文介绍如何使用 HTTP 标题来控制 Internet Explorer 中 Web 页的缓存。

通过 Microsoft Internet Information Server (IIS),您可以在特定 Active Server Pages (ASP) 页的最开始位置,使用以下脚本代码方便地标记高度易变页或敏感页:
<% Response.CacheControl = "no-cache" %><% Response.AddHeader "Pragma", "no-cache" %><% Response.Expires = -1 %>				
更多信息

过期和 Expires 标题

强烈建议所有 Web 服务器都使用针对所有 Web 页的过期方案。如果 Web 服务器不通过 HTTP Expires 响应标题为返回给请求客户端的每种资源提供过期信息,则这种做法是不可取的。目前,多数浏览器和中间代理都很重视此过期信息,并使用它来提高网络的通讯效率。

当服务器上的特定文件需要由客户端更新时,应始终使用 Expires 标题来指定最合理的时间。如果定期更新页,则下一个更新周期将是最有效的响应。例如,假设 Internet 上的某个每日新闻页在每天早晨 5 点更新。此新闻页的 Web 服务器应返回一个带有第二天早晨 5 点这一值的 Expires 标题。这样,在该页实际更改之前,浏览器就不必再联系 Web 服务器。

预期不进行更改的页应使用约为一年的过期日期进行标记。

在许多情况下,Web 服务器在包含信息的服务器上有一个或多个随时可能更改的易变页。因此,该服务器应将这些页的 Expires 标题的值标记为“-1”。当用户在将来进行请求时,Internet Explorer 通常会通过 If-Modified-Since(如果-修改-自)条件请求联系该 Web 服务器,以获取对该页的更新。不过,该页仍会保留在磁盘缓存(“Internet 临时文件”)中,并在适当的情况下(如在使用“后退”和“前进”按钮访问导航历史时,或在浏览器处于脱机模式时)使用,而无须联系远程 Web 服务器。

Cache-Control 标题

不过,有些页非常易变或者非常敏感,以至于它们不需要磁盘缓存。为解决这一问题,Internet Explorer 提供了对 HTTP 1.1 Cache-Control 标题的支持,当 HTTP 1.1 服务器指定 no-cache 值时,这可以完全防止缓存特定的 Web 资源。

由于在浏览器重新联系 Web 服务器之前无法访问不在缓存中的页,因此服务器应慎用 Cache-Control 标题。在多数情况下,使用“Expires:-1”较为可取。

Pragma:No-Cache 标题

遗憾的是,旧式 HTTP 1.0 服务器不能使用 Cache-Control 标题。为了向后兼容 HTTP 1.0 服务器,Internet Explorer 对 HTTP Pragma:no-cache 标题的使用提供了特殊支持。如果客户端通过安全连接 (https://) 与服务器通讯,且服务器在响应中返回 Pragma:no-cache 标题,则 Internet Explorer 不会缓存此响应。

不过请注意,Pragma:no-cache 标题不是为此而设计的。根据 HTTP 1.0 和 1.1 规范,此标题仅在请求的上下文中定义,而不是在响应的上下文中定义,它实际上适用于可能阻止某些重要请求到达目标 Web 服务器的代理服务器。对于将来的应用程序,Cache-Control 标题是控制缓存的适当手段。

HTTP-EQUIV META 标记

HTML 页允许使用特殊的 HTTP-EQUIV 形式的 META 标记,它可在 HTML 文档中指定特定的 HTTP 标题。下面是一个简短的 HTML 页示例,该页同时使用了 Pragma:no-cache 和 Expires: -1:
<HTML><HEAD><META HTTP-EQUIV="Pragma" CONTENT="no-cache"><META HTTP-EQUIV="Expires" CONTENT="-1"></HEAD><BODY></BODY></HTML>				
Pragma:no-cache 仅当在安全连接中使用时才防止缓存。如果在非安全页中使用,Pragma:no-cache META 标记的处理方式与 Expires:-1 相同。该页将被缓存,但被标记为立即过期。

在 Internet Explorer 版本 4 或 5 中,Cache-Control META HTTP-EQUIV 标记被忽略且没有任何作用。要使用 Cache-Control,必须按照上文 Cache-Control 部分所介绍的方法,使用 HTTP 标题来指定 Cache-Control 标题。

请注意,使用标准的 HTTP 标题比使用 META 标记可取得多。META 标记通常必须出现在 HTML HEAD 部分的顶部。而且,已知 Pragma HTTP-EQUIV META 标记至少存在一个问题。有关其他信息,请参阅以下 Microsoft 知识库文章:
222064 “Pragma:No-cache”标记可能无法防止页面被缓存
服务器缓存选项当需要在非 ASP 页上使用 Cache-Control 标题时,可能有必要使用服务器配置中的选项自动添加此标题。请参阅您的服务器文档,以了解如何将 HTTP 标题添加到针对特定目录的服务器响应。例如,在 IIS 4 中,请按照下列步骤操作:
  • 调用 Internet 服务管理器。
  • 使用计算机和服务树,打开默认的 Web 服务器(或所讨论的 Web 服务器),查找包含需要 Cache-Control 标题的内容的目录。
  • 调出此目录的“属性”对话框。
  • 选中“HTTP 标题”选项卡。
  • 单击“自定义 HTTP 标题”组中的“添加”按钮,为标题名添加“Cache-Control”,并为标题值添加“no-cache”。
请记住,最好不要在整个 Web 服务器中全局性地使用此标题。应仅限于对必须绝对禁止在客户端缓存的内容使用。问题清单如果您已经应用了本文中的技巧,但缓存和 Internet Explorer 仍存在问题,请在联系 Microsoft 以寻求技术支持部门的协助之前,逐个步骤地检查这一便于使用的清单。
  • 您是通过 ASP“Response.CacheControl”属性还是通过返回的 HTTP 标题来使用 Cache-Control 标题?这是能够真正防止在 Internet Explorer 中进行缓存的唯一方法。
  • 您是否在使用 Internet Explorer 4.01 Service Pack 2 或更高版本?在该浏览器的更低版本中,无法完全防止缓存。
  • 您已反复检查 Web 服务器是否已启用 HTTP 1.1 并且您是在向 Internet Explorer 返回 HTTP 1.1 响应吗?Cache-Control 标题在 HTTP 1.0 响应中无效。
  • 如果您正在服务器端使用 CGI/ISAPI/Servlets,您是否严格遵守了 HTTP 1.1 规范,特别是与 HTTP 标题的 CRLF 终止符有关的规范?为了确保良好性能,Internet Explorer 通常不容许违反 HTTP 1.1 规范的响应。结果通常会导致标题被忽略或者报告意外的服务器错误。
  • HTTP 标题的拼写是否正确?
参考
有关更多信息,请参阅以下 Microsoft 知识库文章:
189409 INFO:使用 IIS 4.0 控制 Web 页高速缓存

165150 How to Use Pragma:No-cache with IIS and IE
另请参见Hypertext Transfer Protocol -- HTTP/1.1 -- Draft Revision 5(超文本传输协议 -- HTTP/1.1 -- 草案修订版 5)
属性

文章 ID:234067 - 上次审阅时间:12/02/2004 22:20:00 - 修订版本: 3.1

Microsoft Internet Explorer 4.0 128-Bit Edition, Microsoft Internet Explorer 4.01 Service Pack 2, Microsoft Internet Explorer 4.01 Service Pack 1, Microsoft Internet Explorer 4.01 Service Pack 2, Microsoft Internet Explorer 5.0, Microsoft Internet Explorer 5.5, Microsoft Internet Explorer 6.0, Microsoft Internet Explorer 6.0 Service Pack 1

  • kbhowto kbcaching kbfaq KB234067
反馈
<% Response.AddHeader "Pragma", "no-cache"..." />
<% Response.AddHeader "Pragma", "no-cache"..." />
ement('meta');m.name='ms.dqp0';m.content='true';document.getElementsByTagName('head')[0].appendChild(m);" onload="var m=document.createElement('meta');m.name='ms.dqp0';m.content='false';document.getElementsByTagName('head')[0].appendChild(m);" src="http://c1.microsoft.com/c.gif?">