background image

解析

 PHP 和浏览器缓存机制

本文通过一个例子,详细分析了

php 与浏览器的缓存机制的应用实例,有需要的朋友 ,

不妨作个参考。

浏览器的缓存策略,会暂时将浏览过的文件缓存在本地磁盘。当用户重复请求页面时,

告知客户端页面并没有发生改变,可以调用缓存。

 那么如何知道客户端是否有页面缓存呢?

 HTTP 

 

协议层面来说,浏览器发送请求时会先发送如下

HTTP 头:

   Connection Keep-Alive
   Date Sun, 06 May 2012 18:00:36 GMT
   Last-Modified Sun, 06 May 2012 17:31:02 GMT
   Etag ec1f629013925ab0fa4389ba926e8c06
   Keep-Alive timeout=15, max=299
   Server Apache/2.2.16 (Unix) DAV/2
   Vary Accept-Encoding
请注意其中的这两行,描述了页面的缓存信息:
Last-Modified Sun, 06 May 2012 17:31:02 GMT
Etag ec1f629013925ab0fa4389ba926e8c06
这个情况下,如果服务器响应

 304 状态码,浏览器会自觉地从缓存中读取数据;如果响应

 

200 状态码,不管有没有客户端缓存,照样从服务端读取。

按照这个理论支撑,比如站长军团大部分查询结果都是

 ajax 异步获取的,二次访问就

 

都可以通过这种方式进行缓存改造。只要客户端有缓存,就向客户端发送一个

304 响应状

态码,然后退出程序执行。

浏览器发出的请求中包含

 If-Modified-Since 

 

If-None-Match 两个参数:

If-Modified-Since 表示询问数据的最后修改时间是否是某个时间值。然后服务器会检查

 

数据的最后修改时间,如果是该时间则返回

304 状态码,客户端接收到该状态码后直接从

 

本地读取缓存。这种情况有一个前置条件,即本地必须存在缓存资源,浏览器才会发送

If-

Modified-Since 

 

参数,并且值为上一次服务器返回的

Last-Modified 值。

If-None-Match 

 

类似,它由服务器返回的

Etag 值生成,仅仅用于服务器检查数据的修

 

改时间,可以是任意值。考虑到

If-Modified-Since 

 

结合

Last-Modified 的方法并不被所有服

 

务器支持,这里就只考虑使用

etag 的实现。

PHP 

 

中通过

$_SERVER['HTTP_IF_NONE_MATCH'] 可以判断文件是否被浏览器缓存,

代码片段:

//

 

使用

etag 标记控制缓存

$etag = md5(date('Ymd'));
if ($_SERVER['HTTP_IF_NONE_MATCH'] == $etag) {
 header('Etag:' . $etag, true, 304);
 exit();
} else {
 header('Etag:' . $etag);
}
使用当日日期来生成

 etag,这样可以保证缓存最多生效一天时间,这个参数可以根据

需要修改。

补充说明:

即便是

 304 响应,实际上还是会请求服务端,因为需要建立连接来判断是否需要传输数据 ,