1.缓存的工作原理
所有缓存都是由一套规则决定什么时候使用缓存中的副本,这些规则定义在协议中(http1.0/1.1)或由缓存管理员设置(如DBA、浏览器的用户、代理服务器管理员或者应用开发者)。
2.浏览器缓存规则
规则定义在HTTP协议头和HTML页面的Meta标签中。用新鲜度和校验值来规定浏览器是否可以直接使用缓存,还是需要去源服务器获取更新的版本。
新鲜度(过期机制):
1.在有效期内的,含有完整的过期时间控制头信息(HTTP协议报头)。
2.浏览器已经使用过这个缓存副本,并且在一个会话中已经检查过新鲜度。
校验值(验证机制):
服务器返回资源的时候有时在控制头信息带上这个资源的实体标签Etag(Entity Tag),再次请求过程的校验标识。不匹配则被修改或过期了,浏览器需求重新获取资源内容。
3.浏览器缓存控制
使用HTML Meta 标签1
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
页面不被缓存,每次都去服务器拉取。(仅部分浏览器可以支持)
使用缓存有关的HTTP消息报头
一个URI的完整HTTP协议交互过程是由HTTP请求和HTTP响应组成的。在HTTP请求和响应的消息报头中,常见的与缓存有关的消息报头有:
Cache-Control 与 Expires:
- 有效期,控制浏览器读缓存还是读服务器。前者配置更多,优先级更高。
Last-Modified/ETag 与 Cache-Control/Expires:
- 前者是先询问服务器是否有更改,没有则返回304读本地缓存,有则返回改过的数据。
- 后者先读本地有效期内缓存,不发请求。优先级更高。
- 一般情况下同时使用,因为即使点击“刷新“忽略缓存继续请求,也会返回304以减少开销。
Last-Modified 与 ETag:
HTTP1.1中Etag(实体标识)解决几个Last-Modified比较难解决的问题:
- 秒内的新鲜度无法标注。(Last-Modified只到秒级)
- 文件内容没变化Last-Modified却变了,无法使用缓存。
- 服务器时间不一致。
Etag是资源在服务器唯一标识符,先验证ETag -> 在对比Last-Modified -> 是否返回304。
用户操作行为与缓存:
地址栏回车、页面链接跳转、新开窗口、前进后退,两种缓存设置均有效。
刷新:会忽略Expires/Cache-Control的设置,再次发请求,而Last-Modified/Etag还是有效的,服务器会根据情况判断返回304还是200。
强制刷新:全失效,重新从服务器拉资源。
4.哪些请求不能被缓存?
HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求无法被缓存
HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache,或Cache-Control:max-age=0等告诉浏览器不用缓存的请求。
需要根据Cookie,认证信息等决定输入内容的动态请求是不能被缓存的。
POST请求无法被缓存。
经过HTTPS安全加密的请求(有人也经过测试发现,ie其实在头部加入Cache-Control:max-age信息,firefox在头部加入Cache-Control:Public之后,能够对HTTPS的资源进行缓存,参考《HTTPS的七个误解》)。
5.HTML5 本地缓存
浏览器的Application面板,Frames(可看到HTTP文件缓存),Local Storage,Session Storage,indexDB,Web SQL,Cookie,Cache Storage,Application Cache。
HTTP文件缓存
基于HTTP协议的浏览器端文件级缓存机制,缓存原理就是Cache-Control和Etag那套,这里略。
localStorage
本地缓存方案,四个核心API:
- setItem(key,value);
- getItem(key);
- removeItem(key);
- clear();
- 单域名下localStorage在不同浏览器中有长度限制且各不相同;IE8以上为5MB,Chrome或Safari约为2.6MB;
- 只支持简单数据类型,对象类型需JSON.stringify转换
- 多tab打开同域名页面时,localStorage是共享的
sessionStorage
浏览器关闭会清除(使用不多)。
IndexDB
虽可保存50MB的数据在本地(但不安全)。
WebSQL
不是HTML5规范,是单独的规范,HTML5之前就存在;JS端可以操作的小型数据库,兼容性和使用场景有限。
Cookie
- 单域名下有个数限制,总大小4KB;
- document.cookie读取不到HttpOnly类型的cookie;
- 分存储型cookie(设置过期时间)和Session型cookie(不设置过期时间),后者浏览器窗口关闭而消失。
Cache Storage
- 在ServiceWorker中定义,用于保存ServiceWorker声明的cache对象
- 结合ServiceWorker,可做到Web的消息推送、离线、自动更新等。
Application Cache
通过manifest配置文件,在本地有选择的存储JS,CSS,图片等。
优势:离线浏览,快读加载,本地读取,资源更新才会拉取数据,减轻服务器压力。
注意:
- 引用manifest的HTML,及静态资源必须与manifest同源。
- Application Cache已被废弃,将由ServiceWorker代替。
Reference:
http://www.alloyteam.com/2012/03/web-cache-2-browser-cache/#prettyPhoto
https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API