HTTP缓存解析

刷新和输入网址后回车的区别

  1. 强制刷新(ctrl+F5):不理会缓存协商,全部重新获取.此时请求中的Cache-Control值为no-cache
  2. 刷新(F5)时:当点击浏览器上的刷新,客户端发送的请求中的Cache-Control均是max-age=0,表示validate操作,发送请求到服务器要求检查cache,再更新cache,一般得到的是304 Not Modified,表示没变动
  3. 输入网址直接回车时:如果Expired或Cache-Control还未过期,则不会返回304状态,因为浏览器已经不用向web服务器发出请求

Expires与Cache-Control的区别

  1. 给静态资源(HTML文件,图片文件等)加上Expires/Cache-Control Header。如果HTTP Response中有Expires这样的Header的话,浏览器会Cache这个资源,理想状况下(注意,只是理想状况),在Expire Date之前,不会再发HTTP请求给Server要这个资源,不过Expires的值只能是一个固定日期,比如“Thu 27 Nov 2008 07:00:00 GMT”,不能是一个类似“从现在开始之后10年”这样一个随机浮动的值,如果要这样的效果,可以用Cache-Control这样的Header,如果HTTP Resposne中有这样的Header:“Cache-Control: max-age = 100”,表示这个资源在cache中的最大寿命是100秒。
  2. 同一个HTTP Response中可以同时有Expires和Cache-Control,但是Cache-Control权限比Expires大,会override它的。
  3. HTTP/1.0有一个功能比较弱的缓存控制机制:Pragma,使用HTTP/1.0的缓存将忽略Expires和Cache-Control头。

Last-modified/If-Modified-Since与Etag/If-None-Match区别

  1. HTTP的Response中还会有另外一个Header叫Last-Modified,比如“Last-Modified: Thu, 06 Apr 2006 21:17:12 GMT”,浏览器访问一个URI得到这样的Resposne之后,就知道这个资源最后一次的修改时间,下次需要再次获得这个资源的时候,会发一个Request给Server,不过这个Request中有一条“If-Unmodified-Since: Thu, 06 Apr 2006 21:17:12 GMT”,如果在Server端在这个日期之后对这个资源进行了修改,就会照常返回这个资源给Client端,但是如果没有修改,就会返回一个304 (Not Modified) Response而不返回资源,告诉Client端:“这个资源从上次给你之来从来没改过,你放心用你Cache中的好了。” 一个304 Response比一个静态资源通常小多了,这样就节省了网络带宽。
  2. 除了Last-Modified,HTTP Response中还可能有另外一个Header: ETag。在多台负载均衡的服务器环境下,同一个文件可能会有不同的etag或者文件修改日期,浏览器每次都会重新下载,这点要根据实际情况考虑设置。
  3. 比较一下Expires和Last-Modified这两个东西,似乎Last-Modified比不上Expires,因为虽然它能够节省一点带宽,但是还是逃不掉发一个HTTP请求出去,而Expires却使得浏览器干脆连HTTP请求都不用发。不过当用户在IE或者Firefox里面按F5或者点击Refresh按钮的时候(不是在URL栏里重新输入一遍URL然后回车),就算对于有Expires的URI,一样也会发一个HTTP请求出去,所以,Last-Modified还是要用的(返回304),而且要和Expires一起用。

Apache配置

  1. 在expires.conf设置expires,加了expires后,Cache-Control也会有相应换算后的值
    <IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/gif "access plus 1 hour"
    ExpiresByType image/jpeg "access plus 2 hour"
    </IfModule>
    
  2. 对于一般的纯静态页面,如html、gif、jpg、css、js,默认安装的Apache服务器,不会在响应头添加这个字段。

  3. Firefox浏览器接受到相应请求后,如果发现没有Expires字段,浏览器根据文件的类型和“Last-Modified”字段来推断出一个合适的失效时间,并存储在客户端(Firefox的缓存),推测出的时间一般是接受到响应时间后的三天左右,以后的请求就可以根据Firefox的缓存过期时间(而非http指定)来决定是否使用客户端缓存。
  4. Apache服务器默认情况下,会对所有的静态、动态文件的响应头添加ETag字段。如果要关闭ETag,对于Apache,在httpd.conf或者.htaccess中加一行就搞定了:FileETag none
  5. 无论是纯静态页面还是动态页面,Firefox浏览器巧妙地按照接受到服务器响应的时间设置缓存页面的Last-Modified(Firefox的缓存),而不是按照http响应头部中的Last-Modified字段。
  6. 一般纯静态页面本身都会有Last-Modified信息,Apache服务器会读取页面文件中的Last-Modified信息,并添加到http响应头部。
  7. 对于动态页面,如果在页面内部没有通过函数强制加上Expires,例如header(”Expires:”。 gmdate(”D, d M Y H:i:s”) 。 ”GMT”),Apache服务器会把Wed, 11 Jan 1984 05:00:00 GMT作为Expires字段内容,返回给浏览器。
  8. 对于动态页面,如果在页面内部没有通过函数强制加上Last-Modified,例如header(”Last-Modified: ” 。 gmdate(”D, d M Y H:i:s”) 。 ”GMT”),Apache服务器会把当前时间作为Last-Modified,返回给浏览器。
  9. 关闭Last-modified
    LoadModule headers_module modules/mod_headers.so
    
    <FilesMatch "\.(gif|jpg|png)">
    Header unset Last-Modified
    </FilesMatch>
    
  10. 开启gzip
    <ifmodule mod_deflate.c>
    DeflateCompressionLevel 9
    AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-httpd-php
    AddOutputFilter DEFLATE js css
    </ifmodule>
    

原创文章,转载请注明: 转载自Ryan's note

本文链接地址: HTTP缓存解析

  • Share/Bookmark

热门日志

Leave a comment

0 Comments.

Leave a Reply


[ Ctrl + Enter ]