Web 开发人员需知的 Web 缓存知识(3)

发表于:2013-07-30来源:web开发家园作者:sxwgf点击数: 标签:缓存
Expires: Fri, 30 Oct 1998 14:19:41 GMT 显然,如果你要使用Expires头,确保你的Web服务器时间的准备就非常重要了。使用网络时间协议⑥(Network Time Protocol NTP)不失为

  Expires: Fri, 30 Oct 1998 14:19:41 GMT

  显然,如果你要使用Expires头,确保你的Web服务器时间的准备就非常重要了。使用网络时间协议⑥(Network Time Protocol – NTP)不失为一个号方法。如果你的身边有本地系统管理员,可以向他咨询,或者查看下面的百科Add 。

  尽管Expires头很有用,但它有一定的局限性。首先,因为牵扯到时间,Web服务器端的时钟必须和缓存的同步,否则很可能实现不了预期的结果——缓存把前女友当初现女友,把现女友当作过去式——那就悲剧了。

  另外一个问题是,你很容易忘记给某内容设置了一个特定时间,如果返回内容的时候没有更新这个过期时间,则每个请求都是上访到服务器,反而增加了负载和响应时间。

  ⑥网络时间协议(NTP): 以封包交换把两台电脑的时钟同步化的网络协议。NTP使用UDP端口123作为传输层。它是用作抵销可变延迟的影响。NTP是仍在使用中的最古老的网络协 议之一(在1985年前开始)。NTP最初由德拉瓦州大学的Dave Mills设计,他与一群志愿者仍在维护NTP。

  Cache-Control(缓存控制)HTTP头信息

  HTTP 1.1引入了新的头信息:Cache-Control响应头信息,让网站的发布者可以更全面的控制他们的内容,更好地处理Expires的些限制。Cache-Control有用的响应头包括:

  max-age=[秒]:表示在这个时间范围内缓存是新鲜的无需更新。类似Expires时间,不过这个时间是相对的,而不是绝对的。也就是某次请求成功后多少秒内缓存是新鲜的。

  s-maxage=[秒]:类似max-age, 除了仅应用于共享缓存(如代理)。

  public:标记认证的响应才能够被缓存。一般而言,需要认证HTTP请求内容会自动私有化(不会被缓存Add)。

  privateN:允许缓存专门为某一个用户存储响应,比方说在浏览器中;共享缓存一般不会,例如在代理中。

  no-cache:每次在释放缓存副本之前都强制发送请求给源服务器进行验证,这在确保认证有效性上很管用(和public结合使用)或者保证内容必须是即时的,不得无视缓存的所有优点,如国内的微博、twitter等的刷新显示Add。

  no-store:强制缓存在任何情况下都不要保留任何副本。

  must-revalidate:告诉缓存,我给你准备了一些关于新鲜度的信息,在表现的时候要严格遵循之。HTTP允许缓存在某些特定情况下返回过期数据,指定了这个属性,相对于告诉缓存,你丫必须严格遵循我的规则。

  proxy-revalidate:类似must-revalidate,除了只能应用于代理缓存。

  举个板栗:

  Cache-Control: max-age=3600, must-revalidate

  如果Cache-Control和Expires同时存在,Cache-Control说了算N。如果你打算使用Cache-Control头,你应该好好看看”HTTP 1.1 规范“, 详见参考文章以及拓展阅读。

  验证器和验证

  在缓存如何工作这段译文中,我们说过,服务器以及缓存通过验证来判断内容是否改变,在不确定内容是否过期的时候,可以避免本地已经存在副本的时候下载整个内容。

  验证器是很重要的,如果一个都没有,同时没有可用的新鲜度信息(Expires或Cache-Control),缓存一点儿都不会存储内容。

  最常见的验证是通过Last-Modified头信息通信确定文档最后的修改时间,如果缓存有内容存储,会包含Last-Modified信息的,辅助If-Modified-Since请求,我们可以询问服务器内容是否改变了。

  HTTP 1.1引入了一个新的验证器,称为Etag⑦. Etag是每次展现内容改变时候由服务器生成的唯一标识符,由于服务器控制ETag如何生成,当缓存发起If-None-Match请求的时候,如果Etag匹配,就可以确定展示内容其实是一样的。

  ⑦Etag: HTTP协议规格说明定义ETag为”被请求变量的实体值”。另一种说法是,ETag是一个可以与Web资源关联的记号(token)。典型的Web资源 可以一个Web页,但也可能是JSON或XML文档。服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端,以下是服务器端返回 的格式:ETag:”50b1c1d4f775c61:df3″客户端的查询更新格式是这样的:If-None-Match : W / “50b1c1d4f775c61:df3″如果ETag没改变,则返回状态304然后不返回,这也和Last-Modified一样。测试Etag主要 在断点下载时比较有用。

  几乎所有的缓存使用Last-Modified时间作为验证器,Etag验证也开始变得流行。

  所有新一代的Web服务器都对静态内容(如:文件)自动生成ETag和Last-Modified头信息,而你不必做任何设置。但是,服务器对于动态内容(例如:CGI, ASP或数据库生成的网站)并不知道如何生成这些信息,参考一下编写支持缓存的脚本章节;

  创建支持缓存网站的小技巧

  除了使用新鲜度信息以及验证,还有其他一些技巧可以让你网站的缓存更加友好:

  保持URL稳定:这是缓存的金科玉律,如果你为不同页面,不同用户或不同网站提供相同的内容,他们应该使用相同的URL. 这是简单却非常行之有效的方法。例如,你的HTML中的某个引用地址是"/index.html", 则要一直使用这个地址。

  不同地方的图片和其他元素使用同一库。

  对于不经常改变的图片/页面启用缓存,通过将Cache-Control: max-age头信息的值设大一点。

  对于定期更新的内容通过指定max-age或过期时间实现缓存。

  如果资源改变了(尤其下载文件),改变其名字。由于一般这种资源会有很长的过期时间,而服务器上一直是正确的版本;因此,链接这个下载资源的页面需要要比较短的过期时间(//zxx: 我司页面5分钟过期)。否则,会出现服务器的资源是新的,但页面被缓存了,其中的链接地址还是旧的,就会出现新旧版本冲突的可能Add。

  万不得已不要变动文件:否则你要设置一个新的Last-Modified值。另外,当你更新站点的时候,只要上传改动的那些文件,而不要把整个站点都覆盖过去。

  Cookie能不用就不用:Cookie难以被缓存,且大多情境下是没有必要的。如果你非得使用Cookie,建议用在动态页面上。

原文转自:http://web.itivy.com/article-805-1.html