如果每次打开页面都去从服务器加载,服务器压力有点大,同时响应时间也会影响用户体验,大部分的时候,web端的内容是不会改变的,这时候再从服务端拿数据,就有点太没必要了,所以就有了浏览器缓存。
1. 缓存类型。
浏览器缓存控制机制有两种:HTML Meta标签 vs. HTTP头信息
1.1 HTML Meta标签。
主要是通过在html代码里使用meta标签达到控制缓存的目的。
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
浏览器兼容性不好,所以暂不研究。
1.2 http头控制缓存。
1.2.2 两种缓存策略:
Expires:Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。不过Expires 是HTTP 1.0的东西,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。在HTTP 1.1版开始,使用Cache-Control: max-age=秒替代。
Cache-Control:Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。
浏览器第一次请求页面:
再次请求:
文字描述就是:
1. 请求服务器,协商是否缓存页面,如果需要缓存,就返回文件的最后修改时间。
动态请求php文件的返回,不缓存,每次刷新都是200:
Pragma行是为了兼容HTTP1.0,作用与Cache-Control: no-cache是一样的。
静态html文件的请求:
2. 第二次访问,浏览器先去看上次返回的Cache-control,上图未返回,那么就到是否过期这一步了,这时浏览器要发一个http请求,带着上次返回的
这两个数值,在第二次的请求头里面分别是这两个参数:
服务器优先比对ETag,再比对Last-Modified,如果请求带来的和当前服务器上的文件的这些参数一样,那么服务器就返回304,告诉浏览器去缓存里面读取,否则从服务器执行代码返回200。
ETag和Last-Modified解析:
Last-Modified / If_None-Since 这一对,判断文件是否过期的策略是文件的修改时间,对应的值也是文件的最后修改时间,最小单位是秒。
ETag / If-None-Match 这一对,在Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。
两者配合使用,避免一下情况可能出现的缓存bug:
如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间
如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
用户行为对cache-control和ETag和Last-Modified的影响:
无效指的是缓存失效,重新从服务器获取数据或者发起服务器请求。
缓存相关的几种状态码:
服务端怎么设置cache-control
1. 服务器(apache)
apache的expires_module 模块是用来管理这个的。
启动该模块:
LoadModule expires_module modules/mod_expires.so #去掉前面的#号
当然如果我们是租用虚拟主机的话,”httpd.conf”设定档我们一般用户是接触不到的,而在网站根目录里写个”.htaccess”设定档, 我想在运用上相对是较灵活的.”mod_expires”的设定资料除了可以写在Apache的”httpd.conf”设定档中,也可以写 在”.htaccess”设定档里。
范例一:
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault “access plus 10 days”
ExpiresByType text/css “access plus 1 second”
</IfModule>
范例二:
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault A86400
ExpiresByType image/x-icon A2592000
ExpiresByType application/x-javascript A2592000
ExpiresByType text/css A2592000
ExpiresByType image/gif A604800
ExpiresByType image/png A604800
ExpiresByType image/jpeg A604800
ExpiresByType text/plain A604800
ExpiresByType application/x-shockwave-flash A604800
ExpiresByType video/x-flv A604800
ExpiresByType application/pdf A604800
ExpiresByType text/html A900
</IfModule>
范例三:
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault A0
# 1 年
<FilesMatch “\.(flv|ico|pdf|avi|mov|ppt|doc|mp3|wmv|wav)$”>
ExpiresDefault A9030400
</FilesMatch>
# 1 星期
<FilesMatch “\.(jpg|jpeg|png|gif|swf)$”>
ExpiresDefault A604800
</FilesMatch>
# 3 小时
<FilesMatch “\.(txt|xml|js|css)$”>
ExpiresDefault A10800″
</FilesMatch>
</IfModule>
ExpiresActive On是指启用mod_expires功能,相对的Off就是关闭功能.
ExpiresDefault指令是设定预设的过期时间.
从范例一和范例二中,各位可以看到关于时间设定的方式有分两种,一个是文字叙述型,一个是代码加上秒数型.
文字叙述型: “access plus 10 days”意指浏览时起算10天. 过期起算时间有三种,分别是access、now 以及modification.其中access与now意义相同,而modification指的是网页文件的”最后编辑时间”.所以如果要以档桉的最 后编辑时间起算,可以写成这样,”modification plus 10 days”.而时间的指定也很简单,就是英文单字(years、months、weeks、days、hours、minutes、seconds).例 如,可以写成这样,”access plus 1 month 15 days 2 hours”.
代码加上秒数型:
A86400意指浏览时起算1天.格式是代码加上秒数.代码有分两种,”A”等同”access”,意指浏览时起算过期时间.使用代码”A”比较适合应用 在不常变动的网页文件类型,例如图片.另外一种代码是”M”,其意义等同于”modification”,指的是网页文件的”最后编辑时间”.使用代 码”M”比较适合应用在经常变动的网页文件类型,例如HTML页面这类经常更新内容的资料.秒数资料我在文后附上参考资料,可以供各位快速参考.
ExpiresByType指令是依照不同的网页文件型态来做过期时间设定.
例如,ExpiresByType text/css A2592000,意指网站上的CSS风格档3天后过期; ExpiresByType image/gif A604800,意指网站上的Gif图档在7天后过期.
范例三里,使用了<FilesMatch></FilesMatch>来包夹各型态的网页文件,而不是使用”ExpiresByType”指令,这也是一种用法.
mod_headers也可以实现上述的缓存功能:
同样在.htaccess文档里:
<FilesMatch “\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$”>
Header set Cache-Control “max-age=604800, public”
</FilesMatch>
<FilesMatch “\.(xml|txt)$”>
Header set Cache-Control “max-age=18000, public, must-revalidate”
</FilesMatch>
<FilesMatch “\.(html|htm|php)$”>
Header set Cache-Control “max-age=3600, must-revalidate”
</FilesMatch>
2. 服务器语言端(php)
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
不要f5或者ctrl+f5去第二次执行页面查看缓存情况,否则缓存失效,返回304,而不是200,可以通过连接跳转,输入网址,或者地址栏enter键。
参考:
http://blog.csdn.net/21aspnet/article/details/6604814