HTTP Caching 优化网站

fmms 13年前
     <p>        HTTP Caching 用好了,可以极大的减小服务器负载和减少网络带宽。十分有必要深入了解下 http 的 caching 协议。</p>    <p>        先来看下请求/响应过程:</p>    <p style="text-align:center;"><a rel="lightbox[1159]" target="_blank"><img title="HTTP_request" alt="HTTP Caching 优化网站" src="https://simg.open-open.com/show/912ae367075319ea5a4c58a63a618468.jpg" width="437" height="221" /></a></p>    <p style="text-align:center;">http 请求/响应</p>    <p>        1、用 Last-Modified 头</p>    <p>        在第一次请求的响应头返回 Last-Modified 内容,时间格式如:Wed, 22 Jul 2009 07:08:07 GMT。是零时区的 GMT 时间,servlet 中可以用 response.addDateHeader ("Last-Modified", date.getTime ()); 加入响应头。如图:</p>    <p style="text-align:center;"><a rel="lightbox[1159]" target="_blank"><img title="HTTP-caching-last-modified_1" alt="HTTP Caching 优化网站" src="https://simg.open-open.com/show/cec9c18bb9d7cccaea70db97ab657c54.jpg" width="440" height="216" /></a></p>    <p style="text-align:center;">last-modified 和 If-Modified-Since</p>    <p>        Last-Modified 与 If-Modified-Since 对应的,前者是响应头,后者是请求头。服务器要处理 If-Modified-Since 请求头与 Last-Modified 对比看是否有更新,如果没有更新就返回 304 响应,否则按正常请求处理。如果要在动态内容中使用它们,那就要程序来处理了。</p>    <p>        ps:servlet 取 If-Modified-Since 可以用 long last = requst.getDateHeader ("If-Modified-Since");</p>    <p>        2、用 Etag 头</p>    <p>        很多时间可能不能用时间来确定内容是否有更新。那可以用 Etag 头,etag 是以内容计算一个标识。计算的方式可以自己决定,比如可以用 crc32、md5等。</p>    <p style="text-align:center;"><a rel="lightbox[1159]" target="_blank"><img title="HTTP_caching_if_none_match" alt="HTTP Caching 优化网站" src="https://simg.open-open.com/show/adb763b14f8cbff4b814bce15a70053c.jpg" width="441" height="219" /></a></p>    <p style="text-align:center;">Etag 和 If-None-Match</p>    <p>        Etag 与 If-None-Match 是对应的,前者是响应头,后者是请求头。服务器要判断请求内容计算得到的 etag 是否与请求头 If-None-Match 是否一致,如果一致就表示没有更新,返回 304 就可,否则按正常请求处理。可以参考:<a title="用 HttpServletResponseWrapper 实现 Etag 过滤器" href="/misc/goto?guid=4959499177312649175" rel="bookmark" target="_blank">用 HttpServletResponseWrapper 实现 Etag 过滤器</a></p>    <p>        3、用 Expires 头,过期时间</p>    <p>        当请求的内容有 Expires 头的时候,浏览器会在这个时间内不去下载这个请求的内容(这个行为对 F5 或 Ctrl+F2 无效,用 IE7,Firefox 3.5 试了,有效的比如:在地址输入后回车)。</p>    <p style="text-align:center;"><a rel="lightbox[1159]" target="_blank"><img title="HTTP_caching_expires" alt="HTTP Caching 优化网站" src="https://simg.open-open.com/show/924e578acd43d40287de6eba21045058.jpg" width="419" height="220" /></a></p>    <p style="text-align:center;">expires 过期时间</p>    <p>        在 servlet 中可以用 response.addDateHeader ("Expires", date.getTime ()); 添加过期内容。</p>    <p>        ps:在 httpwatch 中可以看到 Result 为 (Cached) 状态的。</p>    <p>        4、用 max-age 的 Cache-Control 头</p>    <p>        max-age 的值表示,多少秒后失效,在失效之前,浏览器不会去下载请求的内容(当然,这个行为对 F5 或 Ctrl+F2 无效)。比如:服务器写 max-age 响应:response.addHeader ("Cache-Control", "max-age=10");</p>    <p>        ps:如果你还要加一些 Cache-Control 的内容,比如:private,最好不要写两个 addHeader,而是一个 response.addHeader ("Cache-Control", "private, max-age=10"); 否则 ie 可能对 max-age 无效,原因它只读第一个 Cache-Control 头。</p>    <p>        小结:</p>    <p>        Last-Modified 与 Etag 头(即是方式 1 和2)还是要请求服务器的,只是仅返回 304  头,不返回内容。所以浏览怎么 F5 ,304 都是有效的。但用 Ctrl+F5 是全新请求的(这是浏览器行为,不发送缓存相关的头)。</p>    <p>        Expires 头与 max-age 缓存是不需要请求服务器的,直接从本地缓存中取。但 F5 会忽视缓存(所以使用 httpwatch 之类的 http 协议监察工具时,不要 F5 误认为 Expires 和 max-age 是无效的)。</p>    <p>        http 协议监察工具:</p>    <p>        Firebox:httpfox、live http header</p>    <p>        IE:httpwatch、iehttpheader</p>    <p>        重要参考文章:<a href="/misc/goto?guid=4958538614099693147" target="_blank">How To Optimize Your Site With HTTP Caching</a></p>    <div id="come_from">           来自:     <a id="link_source2" href="/misc/goto?guid=4959499177503405732" target="_blank">blog.chenlb.com</a>    </div>