缓存相关

来源:互联网 发布:linux view 最后一页 编辑:程序博客网 时间:2024/05/22 08:19

注意:一般情况下,需要Cache-Control/Expires配合Last-Modified/ETag一起使用,因为即使服务器设置缓存时间, 当用户点击“刷新”按钮时,浏览器会忽略缓存继续向服务器发送请求,这时Last-Modified/ETag将能够很好利用304,从而减少响应开销(这里只是避免了服务器响应数据,也就是说如果响应304。服务不再返回数据,浏览器直接使用缓存文件,但是浏览器端依旧会发送请求)。


首先,先检查而expires和cache-control(两者都存在的时候遵循http1.1的cache-control),如果在过期时间之内,就直接从缓存读取(此时返回200 from cache ,其实并没有发送请求,这只是浏览器伪造的请求)。如果过期了就判断有没有Etag(当Etag和lastModifued都存在时遵循Etag),然后发送请求会带着if-None-Match和if-Modified-since,然后看服务器端响应,如果存在Etag的话,就跟if-None-Matcth比较;如果不存在Etag,就让if-Modified-since与服务器响应的last-Modified比较。

有两种方式:

第一种在上一次服务端告诉客户端约定的有效期的同时,告诉客户端该文件最后修改的时间,当再次试图从服务端下载该文件的时候,check下该文件有没有更新(对比最后修改时间),如果没有,则读取缓存;

第二种方式是在上一次服务端告诉客户端约定有效期的同时,同时告诉客户端该文件的版本号,当服务端文件更新的时候,改变版本号,再次发送请求的时候check一下版本号是否一致就行了,如一致,则可直接读取缓存。

200 from cache
设置 header("Expires:".gmdate("D, d M Y H:i:s", time()+$cache_time )."GMT"); 
状态码依然是200,时间依然是旧的时间,Size栏目显示为from cache,表示内容是直接从浏览器读取,浏览器根本就没有向服务器发起http请求
Expires比Last-Modified缓存效果更好是吧,因为本地有缓存数据时,不需要向服务器发起http请求,服务器的并发数会明显的减少,可以少处理很多http请求

Last-Modified/If-Modified-Since

Last-Modified/If-Modified-Since就是上面说的当有效期过后,check服务端文件是否更新的第一种方式,要配合Cache-Control使用。比如第一次访问我的主页simplify the life,会请求一个jquery文件,响应头返回如下信息:

ETag/If-None-Match

ETag/If-None-Match则是上文大话中说的第二种check服务端文件是否更新的方式,也要配合Cache-Control使用。实际上ETag并不是文件的版本号,而是一串可以代表该文件唯一的字符串(Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。),当客户端发现和服务器约定的直接读取缓存的时间过了,就在请求中发送If-None-Match选项,值即为上次请求后响应头的ETag值,该值在服务端和服务端代表该文件唯一的字符串对比(如果服务端该文件改变了,该值就会变),如果相同,则相应HTTP304,客户端直接读取缓存,如果不相同,HTTP200,下载正确的数据,更新ETag

怎样判断服务端的文件没有更新?

方法1:告诉客户端该文件的最后修改时间;

方法2:告诉客户端该文件的版本号

  Last-Modified:Wed, 18 Jun 200814:22:27 GMT //上次更新 config 的时间
    Cache-Control: max-age=600 //缓存有效时间
    Expires: Wed, 18Jun 2008 14:48:39 GMT
 //缓存失效时间:当前时间 +Cache-Control
    Date: Wed, 18 Jun 2008 14:38:39 GMT
  //当前时间

Expires = Date+ Cache-control

cache-control、Exprires和Date

这几个参数的组合,表示告诉浏览器:这个文件在多长时间之内不会更改,在这个时间内不需要再 request,保守起见,我设置了10分钟。

Last-Modified 与if-modified-since(针对方法1)

在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务期端最后被修改的时间,格式类似这样:

Last-Modified: Fri, 12 May 2006 18:53:33 GMT

客户端第二次请求此URL时,根据 HTTP 协议的规定,浏览器会向服务器传送 If-Modified-Since 报头,询问该时间之后文件是否有被修改过:

If-Modified-Since: Fri,12 May200618:53:33 GMT

如果Last-Modified与If-Modified-Since相同,则相应304,从缓存读取数据;

如果不相同,相应200,同时通过相应头更新last-modified。

ETag和if-none-match(针对方法2)

 HTTP 协议规格说明定义ETag为“被请求变量的实体值” (参见 —— 章节 14.19)。另一种说法是,ETag是一个可以与Web资源关联的记号(token)。典型的Web资源可以一个Web页,但也可能是JSON或XML 文档。服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端,以下是服务器端返回的格式:

ETag: "50b1c1d4f775c61:df3"

客户端的查询更新格式是这样的:

If-None-Match: W/"50b1c1d4f775c61:df3"

如果ETag没改变,则返回状态304然后不返回,这也和Last-Modified一样。本人测试Etag主要在断点下载时比较有用。

Last-ModifiedEtags如何帮助提高性能?

聪明的开发者会把Last- Modified 和ETags请求的http报头一起使用,这样可利用客户端(例如浏览器)的缓存。因为服务器首先产生 Last-Modified/Etag标记,服务器可在稍后使用它来判断页面是否已经被修改。本质上,客户端通过将该记号传回服务器要求服务器验证其(客户端)缓存。
过程如下:
1> 客户端请求一个页面(A)。
2> 服务器返回页面A,并在给A加上一个Last-Modified/ETag。
3> 客户端展现该页面,并将页面连同Last-Modified/ETag一起缓存。
4> 客户再次请求页面A,并将上次请求时服务器返回的Last-Modified/ETag一起传递给服务器。
5> 服务器检查该Last-Modified或ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304和一个空的响应体。

0 0
原创粉丝点击