浏览器缓存的基础
浏览器缓存会根据进来的请求保存输出内容的副本,例如html页面, 图片,文件(统称为副本),然后,当下一个请求来到的时候:如果是相同的URL,缓存直接使用副本响应访问请求,而不是向源服务器再次发送请求。一般都能在浏览器的设置对话框中发现关于缓存的设置,通过在你的电脑上僻处一块硬盘空间用于存储你已经看过的网站的副本。
- 使用缓存主要有2大理由:
- 减少相应延迟:因为请求从缓存服务器(离客户端更近)而不是源服务器被相应,这个过程耗时更少,让web服务器看上去相应更快;
- 减少网络带宽消耗:当副本被重用时会减低客户端的带宽消耗;客户可以节省带宽费用,控制带宽的需求的增长并更易于管理。
浏览器缓存如何工作
所有的缓存都用一套规则来帮助他们决定什么时候使用缓存中的副本提供服务(假设有副本可用的情况下);一些规则在协议中有定义(HTTP协议1.0和1.1),一些规则由缓存的管理员设置(浏览器的用户或者代理服务器的管理员);
一般的规则如下:
-
如果响应头信息:告诉缓存器不要保留缓存,缓存器就不会缓存相应内容;
-
如果请求信息是需要认证或者安全加密的,相应内容也不会被缓存;
-
如果在响应中不存在校验器(ETag或者Last-Modified头信息),缓存服务器会认为缺乏直接的更新度信息,内容将会被认为不可缓存。
-
一个缓存的副本如果含有以下信息,则内容将会被认为是足够新的,不会请求服务器:
-
含有完整的过期时间和寿命控制头信息,并且内容仍在保鲜期内;
-
浏览器已经使用过缓存副本,并且在一个会话中已经检查过内容的新鲜度;
-
缓存代理服务器近期内已经使用过缓存副本,并且内容的最后更新时间在上次使用期之前;
-
够新的副本将直接从缓存中送出,而不会向源服务器发送请求;
5.如果缓存的副本已经太旧了,缓存服务器将向源服务器发出请求校验服务端原件的请求,用于确定是否可以继续使用当前拷贝继续服务;
浏览器请求与缓存的关系流程图
浏览器第一次请求:
浏览器再次请求时:
控制缓存方式
1.添加meta元信息
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
以上方式效率并不高,因为只有几种浏览器会遵循这个标记(那些真正会”读懂”HTML的浏览器),没有一种缓存代理服务器能遵循这个 规则(因为它们几乎完全不解析文档中HTML内容)
2.HTTP协议定义的缓存机制
- Expires策略
Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。不过Expires 是HTTP 1.0的东西,现在默认浏览器均默认使用HTTP1.1,所以它的作用基本忽略。
- Cache-control策略
Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。
3.HTML5的LocalStorage和sessionStorage
LocalStorage在PC上的兼容性不太好,而且当网络速度快、协商缓存响应快时使用localStorage的速度比不上304。并且不能缓存css文件。而移动端由于网速慢,使用localStorage要快于304
4.浏览器缓存的使用
- ajax
方式一:用POST替代GET(不推荐):POST模式的返回内容不会被大部分缓存服务器保存,如果你发送内容通过URL和查询(通过GET模式)的内容可以缓存下来供以后使用;
方式二:使用HTTP协议定义的缓存机制
1、在ajax发送请求前加上
xmlHttpRequest.setRequestHeader("Cache-Control","no-cache");
或者
xmlHttpRequest.setRequestHeader("If-Modified-Since","0″);
2.jQuery里设置禁止缓存的方法:
<script type="text/javascript" language="JavaScript">
$.ajaxSetup ({
cache: false //close AJAX cache
});
</script>
方式三:添加时间戳
URL 参数后加上 "?timestamp=" + new Date().getTime()
;
- js文件
1.添加时间戳
<script type="text/javascript" src="/js/common.js" ></script>
在后面加一个时间戳来解决。这样url地址每次变化,浏览器就会请求服务端的js,而不会使用缓存
2.添加版本号
<script type="text/javascript" src="js/common.js?t=20150622" ></script>
如果下一次修改了这个js文件,那么发布的时候,就修改日期,这样做到了程序员自己控制的办法
<script type="text/javascript" src="js/common.js?t=20150628" ></script>