Bookmark and Share

Lee's 程序人生

HTML CSS Javascript XML AJAX ATLAS C# C++ 数据结构 软件工程 设计模式 asp.net Java 数字图象处理 Sql 数据库
  博客园  :: 首页  :: 新随笔  :: 联系 :: 管理

关于Etag的问题

Posted on 2008-06-13 10:07  analyzer  阅读(667)  评论(0)    收藏  举报

用PHP控制用户浏览器缓存!

原文地址: http://www.longbill.cn/blog/index.php?id=56
    你写的php程序是否高效?你是否会担心自己的程序太庞杂,执行速度很慢?你是否用过php动态生成图片?
   其实每种浏览器都有缓存策略,会暂时将每一个浏览过的文件缓存在一个特殊的文件夹里。我们就可以在用户重复提交页面请求的时候,告诉用户这个页面没有改变,可以调用缓存。 那我们怎么知道用户有没有这个页面的缓存数据呢? 其实浏览器在发送请求的时候会先发送http头,一般象这样:

[quote]Date: Sun, 30 Jul 2006 09:18:11 GMT
Content-Type: image/gif
Last-Modified: Wed, 19 Jul 2006 07:40:06 GMT
ETag: "8c55da8d6abc61:2327"
Content-Length: 14757
其中Last-Modified: Wed, 19 Jul 2006 07:40:06 GMT[/quote]

ETag: "8c55da8d6abc61:2327"就是有关页面的缓存信息的。然后如果服务器返回的响应代码不是HTTP 200 (OK),而是 304的话,浏览器就会从缓存中读取数据。
    根据这个原理,我写了一个函数,这个函数可以用在不经常更新或者需要经常刷新的页面,可以大大减轻服务器的负担,因为它如果发现客户端有缓存,就向客户端发送一个304响应,然后停止程序的执行。
    演示地址:http://www.longbill.cn/down/sample/etag.php
[code]<?php
cache();
echo date("Y-m-d H:i:s"); 

function cache()
{//author:Longbill ( http://www.longbill.cn/ )
      $etag = "eeee";  //标记字符串,可以任意修改
      if ($_SERVER['HTTP_IF_NONE_MATCH'] == $etag)
      {
            header('Etag:'.$etag,true,304);
            exit;
      }
      else header('Etag:'.$etag);
}
?>[/code]

fcicqbbs 2006-7-30 10:29 AM
 
文章不错.不过好象和规则有点冲突

(任何参赛文章在喜悦村发表24小时内不得转投其他网站,包括作者个人网站及博客等,以免造成认定上的混乱)

另外能否分析一下大多数服务器etag是如何得到的?

longbill 2006-7-30 10:34 AM
 
楼上说的对啊,其实我是在我的blog上发表了之后就马上发到这里来了。至于参赛则是我发了之后才看到的。

longbill 2006-7-30 10:35 AM
 
php里面,来自客户端的etag在$_SERVER的HTTP_IF_NONE_MATCH项里。
也就是$_SERVER['HTTP_IF_NONE_MATCH']

qh663 2006-7-30 01:16 PM
 
Etag是页面的实体标签。最好是网站页面中的唯一性

longbill 2006-7-31 06:12 AM
 
[quote]Etag是页面的实体标签。最好是网站页面中的唯一性[/quote]

?????

菜鸟也要有理想 2006-7-31 04:31 PM
 
支持
这个对于大流量的站点很有用

游戏人间 2006-8-1 01:31 AM
 
:lol:lol贴的代码占比例挺大.

qh663 2006-8-1 02:55 AM
 
Etag是实体标签,强加定义没什么意思。看一下更简单的,运行下例就知道了。
header('Last-Modified:Tue,01 Aug 2000 10:26:24 GMT');

echo 
date("Y-m-d H:i:s");

服务端只输出一次,以后的都在客户端的缓存里读。

starDust 2006-8-8 01:41 AM
 
如何控制缓存时间啦?假如我想缓存一个小时,一小时后第一次访问生成新的内容
或者,能在php中强制清除缓存吗?

monqu 2006-8-8 01:52 AM
 
那如果数据库的资料已经被更新了,那怎么办?也就是说如何判断当同一个查询资料更新时,显示最新的资料,不变时缓存输出?

qh663 2006-8-8 02:39 AM
 
[quote]原帖由 [i]monqu[/i] 于 2006-8-8 09:52 发表
那如果数据库的资料已经被更新了,那怎么办?也就是说如何判断当同一个查询资料更新时,显示最新的资料,不变时缓存输出? [/quote]
把你的最后更新资料的时间,改变为date('D,d M Y H:i:s')格式。
也可以相对一个时间,比如在客户端缓存1小时
$time = date('D,d M Y H:i:s',time()-3600);

header('Last-Modified:'.$time.' GMT');
......

[[i] 本帖最后由 qh663 于 2006-8-8 10:40 AM 编辑 [/i]]

monqu 2006-8-9 09:01 AM
 
楼上的大哥可能误会了我的意思,我所说的是那种更新\交互很及时的情况,比如你刚修改了1个商品的价格,那你刷新后应该看到的商品价格就是刚改过的,而不是一段时间才看到.
我印象中mysql好象有这种机制可以判断数据库的资料是不是被更新了.不知道是否哪位会知道,或者否定我这个想法.

[[i] 本帖最后由 monqu 于 2006-8-9 05:02 PM 编辑 [/i]]

axgle 2006-8-17 07:15 AM
 
[quote]原帖由 [i]longbill[/i] 于 2006-7-30 06:34 PM 发表
楼上说的对啊,其实我是在我的blog上发表了之后就马上发到这里来了。至于参赛则是我发了之后才看到的。 [/quote]
看上去很眼熟:
http://www.phpx.com/happy/viewthread.php?tid=111324
我想这只是巧合吧 ;P

<?php 

cache
(); 

echo 
date("Y-m-d H:i:s");    


function 
cache() 

{
//author:Longbill ( www.longbill.cn ) 

         
$etag "eeee";     //标记字符串,可以任意修改 

         
if ($_SERVER['HTTP_IF_NONE_MATCH'] == $etag

         { 

                 
header('Etag:'.$etag,true,304); 

                 exit; 

         } 

         else 
header('Etag:'.$etag); 



?>

http://www.phpx.com/happy/archiver/tid-121592.html