atitit。浏览器缓存机制 and 微信浏览器防止缓存的设计 attilax 总结html
1.6. Etag 主要为了解决 Last-Modified 没法解决的一些问题。 4url
3. html meta法 5.net
若是已通过期了,那就去服务器请求,等待服务器响应,这是很费时间的,服务器若是发现资源没有改变过,那么就会返回304,告诉浏览器,我没变过,你去读缓存吧,因而浏览器也不用从服务器拉数据了,然而,等待服务器响应也是一个很要命的问题,在网速发达的今天,等一个响应,有时比下载还慢。
304是HTTP状态码,服务器用来标识这个文件没修改,不返回内容,浏览器在接收到个状态码后,会使用浏览器已缓存的文件
固然浏览器在判断到缓存过时后,请求中头部附带If-Modified-Since字段去拉取某一个文件,服务器会根据这个指定的时间去判断,若是这个时间点以后没有修改,也会返回304
做者:: 老哇的爪子 Attilax 艾龙, EMAIL:1466519819@qq.com
转载请注明来源: http://blog.csdn.net/attilax
若是是用浏览器刷新的,那么浏览器不会去判断max-age了,直接去服务器拿,若是服务器判断资源没变过,则仍是会返回304,和
读取过的文件在http header设置了expire(http 1.0) / max-age(http 1.1),在正常浏览时,如未超时,而且浏览器也有缓存时,会直接从浏览器缓存取出,但若是你在当前页面按刷新按钮(F5)时,有的浏览器会再次向服务器发出请求,有些浏览器不会。
Expires 头部字段提供一个日期和时间,在该日期前的全部对该资源的请求都会直接使用浏览器缓存而不用向服务器请求(注意:cache-control max-age 和 s-maxage 将覆盖 Expires 头部。)
Expires 字段接收如下格式的值:“Expires: Sun, 08 Nov 2009 03:37:26 GMT”。
可是使用Expires存在服务器端时间和浏览器时间不一致的问题。
Cache-Control 是最重要的规则。这个字段用于指定全部缓存机制在整个请求/响应链中必须服从的指令。该字段一般覆盖默认缓存算法。另外,缓存指令是单向的,即请求中存在一个指令并不意味着响应中将存在同一个指令。
简单地说,该字段用于控制浏览器在什么状况下直接使用本地缓存而不向服务器发送请求。通常具备如下值:
· public: 全部内容都将被缓存
· private: 内容只缓存到似有缓存中
· no-cache: 全部内容都不会被缓存
· no-store: 全部内容都不会被缓存到缓存或者internet临时文件中
· must-revalidation/proxy-revalidation: 若是缓存的内容失效,请求必须发送到服务器/代理以进行从新验证
· max-age=xxx( xxx is numeric ): 缓存的内容将在 xxx 秒后失效, 这个选项只在HTTP 1.1可用, 并若是和Last-Modified一块儿使用时, 优先级较高
其中最经常使用的属性即是 max-age, 这个字段很简单,就是浏览器在资源成功请求后的制定时间内,都将直接调用本地缓存和不会向服务器去请求数据。
Last-Modified和E-tag的做用都是向服务器确认当前缓存文件是否为最新。抛开功能不看,这两个字段的表现以下:
· 若服务器在响应一个资源时添加了Last-Modified字段,那么当下一次浏览器再一次向服务器请求该资源时(前提是浏览器中上一次的资源被缓存过了),会在请求header中包含If-Modified-Since字段,且值与服务器第一次响应给浏览器的Last-Modified字段一致
· 若服务器在响应一个资源时添加了ETag字段,那么当下一次浏览器再一次向服务器请求该资源时(前提是浏览器中上一次的资源被缓存过了),会在请求header中包含If-None-Match字段,且值与服务器第一次响应给浏览器的ETag字段一致
那么上述是遵循了Http协议的浏览器会自动实现的,而要实现304的功能,就须要服务器(好比Apache对于静态资源会自动实现这两个字段的响应)或者咱们手动在服务器端编写响应的逻辑来实现。
· 若服务器在收到的资源请求中发现含有Last-Modified字段,则说明浏览器中包含了该资源的某一版本的缓存,此时服务器端将根据该字段的值进行必定的逻辑判断,以决定让浏览器直接使用已有的缓存(返回304)仍是将最新的文件发送过去(200,发送新文件并更新Last-Modified字段)
· 若服务器在收到的资源请求中发现含有If-None-Matc字段,则说明浏览器中包含了该资源的某一版本的缓存,此时服务器端将根据该字段的值进行必定的逻辑判断,以决定让浏览器直接使用已有的缓存(返回304)仍是将最新的文件发送过去(200,发送新文件,并更新ETag)
若同时使用了Last-Modified和ETag,正确的作法应该是当二者都符合条件时,才返回304
· 一些文件也许会周期性的更改,可是他的内容并不改变(仅仅改变的修改时间),这个时候咱们并不但愿客户端认为这个文件被修改了,而从新GET。这种状况下能够将某个能用来代表文件内容是否被更改的值(好比md5)来做为ETag
· 某些文件修改很是频繁,好比在秒如下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改没法判断(或者说UNIX记录MTIME只能精确到秒)
· 某些服务器不能精确的获得文件的最后修改时间
通常咱们打开(或者更新)一个页面(或者资源)有几种方式:
· 在地址栏中输入地址,而后回车
· 激活当前页面地址,而后回车
· F5刷新页面
· 单机Back/Forward按钮
上面几种方式对资源的请求,会产生不一样的结果,而且各浏览器的表现并不一致。具体的区别能够参考鸟哥的《浏览器缓存机制》
其中你们须要注意的一点是,刷新页面(F5或者刷新按钮),不论是否设置了max-age,都会从新像服务器发送请求。可是这不影响304逻辑。
最后, 归纳下关键的结论:
关键结论 |
|
打开新窗口 |
若是指定cache-control的值为private、no-cache、must-revalidate,那么打开新窗口访问时都会从新访问服务器。而若是指定了max-age值,那么在此值内的时间里就不会从新访问服务器,例如:Cache-control: max-age=5 表示当访问此网页后的5秒内再次访问不会去服务器. |
在地址栏回车 |
若是值为private或must-revalidate,则只有第一次访问时会访问服务器,之后就再也不访问。若是值为no-cache,那么每次都会访问。若是值为max-age,则在过时以前不会重复访问。 |
按后退按扭 |
若是值为private、must-revalidate、max-age,则不会重访问,而若是为no-cache,则每次都重复访问. |
按刷新按扭 |
不管为什么值,都会重复访问. |
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
这个好像对wechat不起做用。
JSP:
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
覆盖getLastModified方法,响应消息中无LastModified头字段
window.location="a-intro.html?"+Math.random();
这个对wechat起做用。。
rdm。html
<script>
window.location="a-intro.html?"+Math.random();
</script>
(3 条消息) 浏览器文件缓存和304的区别? - 知乎.htm
[转载](转)浏览器缓存和304小结_hugh_新浪博客.htm
(very detail good)浏览器缓存机制 风雪之隅.htm