计算机教程

当前位置:3522.com > 计算机教程 > PHP设置图片浏览器缓存方法介绍3522.com

PHP设置图片浏览器缓存方法介绍3522.com

来源:http://www.4sports-uk.com 作者:3522.com 时间:2019-06-22 18:58

一、Etag的使用

客户端和浏览器之间的交互:

 ---------        1          ---------   |         |---------------->|         |  |         |   2(200,OK)   |         |  |         |<----------------|         |  |    客   |    3(Etag)     |    服   |  |         |---------------->|         |  |    户   |    4(304)      |    务   |  |         |<----------------|         |  |    端   |    3(强制刷新)  |    端   |  |         |---------------->|         |  |         |   6(200,OK)   |         |  |         |<----------------|         |   ---------                   ---------                   <Created By Barret Lee>
  1. 客户端向服务器请求资源S

  2. 服务器返回数据,并带上一个 Etag

  3. 客户端再次请求资源S,由于上次服务器给他返回了一个 Etag,这次请求的时候他会带上这个 Etag

  4. 服务器发现请求中包含 Etag,判断是否过期,没过期则返回 304 Not Modified

  5. 客户端强制刷新(如chrome中ctrl shift R刷新页面),请求中剔除 Etag

  6. 服务器未发现请求中包含 Etag,返回资源S,并带上一个 Etag

过程如下:

三、小结

Etag 在缓存处理中用的比较广泛,使用它可以减少一些不必要请求的带宽的占用。服务器输出的内容不变,浏览器就应该使用缓存,没必要每次都向服务器端索要数据,造成不必要的浪费。

从上面我们可以看到,如果想拿到 Etag,就必须先拿到要输出的数据,所以 Etag 只能减少带宽的占用,并不能降低服务器的消耗。如果是静态页面,可以判断文件最近一次的修改时间(Last-Modified),获取文件上次修改时间的消耗比拿到整个数据的消耗要小的多。所以很多时候 Etag 都是配合这 Last-Modified 一起使用的。

上面的 php 和 node 代码演示,很明显的差异就是,node 更加细致,或者说他更加底层,我们可以获取的几乎都是未加修饰的原始数据,从数据量的交互和可操控性来看,我更偏向于 node 的使用。

 


 代码如下

HTTP 提供了许多页面缓存的方案,其中属 Etag 和 Last-Modified 应用最广。本文会先介绍 Etag 的应用场景,然后说说他在 php 和 node 中的使用。

cache();
echo date(”Y-m-d H:i:s”);
function cache()
{
       $etag = “http://longrujun.name”;
       if (isset($_SERVER['HTTP_IF_NONE_MATCH'])  &&
$_SERVER['HTTP_IF_NONE_MATCH'] == $etag)
       {
              header(’Etag:’.$etag,true,304);
              exit;
       }
       else header(’Etag:’.$etag);
}

2. node 中的 Etag

与 php 有些不同,从 $_SERVER 中拿到的内容是经过 Apache 包装过的,而 node 获取的数据是最原始的。

var hashStr = "A hash string.";  var hash = require("crypto").createHash('sha1').update(hashStr).digest('base64');    require("http").createServer(function(req, res){      if(req.headers['if-none-match'] == hash){          res.writeHead(304);          res.end();          return;      }      res.writeHead(200, {          "Etag": hash      })      res.write(hashStr);      res.end();  }).listen(9999);

上面对 hashStr(输出的内容) 进行了简单的处理,并将其作为 Etag 放在 head 中输出,上面的代码一目了然,我就不解释了。

4、Last-Modified和Expires
Last-Modified标识能够节省一点带宽,但是还是逃不掉发一个HTTP请求出去,而且要和Expires一起用。而Expires标识却使得浏 览器干脆连HTTP请求都不用发,比如当用户F5或者点击Refresh按钮的时候就算对于有Expires的URI,一样也会发一个HTTP请求出去, 所以,Last-Modified还是要用的,而 且要和Expires一起用。

1. php 中的 Etag

<?php      $str = "Barret Lee";      $Etag = md5($str);        if(array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER) and $_SERVER['HTTP_IF_NONE_MATCH'] == $Etag){          header("HTTP/1.1 304 Not Modified");          exit();      } else {          header("Etag:" . $Etag);          echo $str;      }  ?>

Etag 是一个字符串,我们一般使用该请求对应响应输出的 md5 值作为 Etag,可以简单地理解为文件的版本号。在 php 中存在两个获取 md5 的函数,一个是针对字符串的,就是 md5(),然后就是针对文件的, md5_file()

首先判断在请求中是否包含 'HTTP_IF_NONE_MATCH' 这个 key,如果包含并且其值为之前的 md5 值,则返回 304,否则输出 Etag 以及内容。

1 Last-Modified: Tue, 24 Feb 2009 08:01:04 GMT
客户端第二次请求此URL时,根据 HTTP 协议的规定,浏览器会向服务器传送 If-Modified-Since 报头(Http Request Header),询问该时间之后文件是否有被修改过:

二、代码实现

第一次请求数据:

3522.com 1

浏览器在接受到服务器发过来的 Etag 后,会保存下来,下次请求的时候会将它放在请求头中,其 key 值为 If-None-Match。

3522.com 2

服务器拿到 If-None-Match 之后,对比之前的 Etag,如果没变,则返回 304 Not Modified.

1 If-Modified-Since: Tue, 24 Feb 2009 08:01:04 GMT
如 果服务器端的资源没有变化,则自动返回 HTTP 304 (Not Changed.)状态码,内容为空,这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器时,则重新发出资源,返回和第一次请求时类似。从而 保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。

本文地址:http://www.cnblogs.com/hustskyking/p/etag-in-node.html,转载请注明源地址。

当下次需要发Request索要同一个URI的时候,浏览器同时发出一个If-None-Match报头( Http Request Header)此时包头中信息包含上次访问得到的Etag: “5d8c72a5edda8d6a:3239″标识。

1 Etag: “5d8c72a5edda8d6a:3239″
客户端的查询更新格式是这样的:

3.1、Expires
如expires.php

上面的方法超级简单,下面看个完整实例

 代码如下

二、对于非实时交互动态页面中Epires和Etag处理
对数据更新并不频繁、如tag分类归档等等,可以考虑对其cache。简单点就是在非实时交互的动态程序中输出expires和etag标识,让其缓存。 但需要注意关闭session,防止http response时http header包含session id标识;

2、Etag工作原理

3、Expires
给出的日期/时间后,被响应认为是过时。如Expires: Thu, 02 Apr 2009 05:14:08 GMT
需和Last-Modified结合使用。用于控制请求文件的有效时间,当请求数据在有效期内时客户端浏览器从缓存请求数据而不是服务器端. 当缓存中数据失效或过期,才决定从服务器更新数据。

HTTP/1.x 304 Not Modified
Date: Tue, 03 Mar 2009 05:03:56 GMT
Content-Type: image/jpeg
Content-Length: 83185
Last-Modified: Tue, 24 Feb 2009 08:01:04 GMT
Cache-Control: max-age=2592000
Expires: Thu, 02 Apr 2009 05:14:08 GMT
Etag: “5d8c72a5edda8d6a:3239″

header(’Cache-Control: max-age=86400,must-revalidate’);
header(’Last-Modified: ‘ .gmdate(’D, d M Y H:i:s’) . ‘ GMT’ );
header(”Expires: ” .gmdate (’D, d M Y H:i:s’, time() ‘86400′ ). ‘ GMT’);

 代码如下

$imagePath = "path/to/some/image";
 
$eTag = $imagePath;
3522.com,$eTag .= fileMTime($imagePath);
$eTag = md5($eTag);
 
if((isset($_SERVER['HTTP_IF_NONE_MATCH'])) &&
(stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) == $eTag)) {
    header("HTTP/1.1 304 Not Modified", TRUE, 304);
    exit();
}
 
header("ETag: ".$eTag);
header("Content-Type: image/png");
readFile($imagePath);
exit();

表 1. 常用 cache-directive 值
Cache-directive 说明
public 所有内容都将被缓存
private 内容只缓存到私有缓存中
no-cache 所有内容都不会被缓存
no-store 所有内容都不会被缓存到缓存或 Internet 临时文件中
must-revalidation/proxy-revalidation 如果缓存的内容失效,请求必须发送到服务器/代理以进行重新验证
max-age=xxx (xxx is numeric) 缓存的内容将在 xxx 秒后失效, 这个选项只在HTTP 1.1可用, 并如果和Last-Modified一起使用时, 优先级较高

客户端第二次请求此URL时,根据 HTTP 协议的规定,浏览器会向服务器传送报头(Http Request Header),服务器端响应并记录相关记录属性标记文件没有发生改动,服务器端返回304,直接从缓存中读取:

5、Etag和Expires
如果服务器端同时设置了Etag和Expires时,Etag原理同样,即与Last-Modified/Etag对应的Http Request Header:If-Modified-Since和If-None-Match。我们可以看到这两个Header的值和Web Server发出的Last-Modified,Etag值完全一样;在完全匹配If-Modified-Since和If-None-Match即检查 完修改时间和Etag之后,服务器才能返回304.

本文由3522.com发布于计算机教程,转载请注明出处:PHP设置图片浏览器缓存方法介绍3522.com

关键词: 3522.com