Web 缓存有不少种,好比数据库缓存、代理服务器缓存、CDN 缓存,以及浏览器缓存。html
浏览器缓存指的是将缓存文件保存在客户端,通常是经过 HTTP 进行缓存。算法
HTTP/1.1 标准中固定了 HTTP 缓存的两种方式: expiration 机制 和 validation 机制。前者是经过减小服务器和浏览器的循环次数,后者经过只响应头部信息较少网络带宽。(有些参考资料,将前者称为强缓存,后者称为协商缓存)chrome
强缓存优先级高于协商缓存,也就是说,当执行强缓存的规则,缓存生效,则再也不执行协商缓存。数据库
expiration 机制经过 Expires
和 Cache-Control
两个字段来标明失效规则。浏览器
Expires缓存
Expires 的值为服务器返回的到期时间,即下一次请求时,请求时间小于服务器返回的到期时间,直接使用缓存数据。可是因为客户端和服务器可能有时间差,会致使较大的缓存命中偏差,因此 HTTP/1.1 使用了 Cache-Control
替代。安全
Cache-Control服务器
Cache-Control 是很是重要的规则。取值以下:cookie
注意,Cache-Control 是一个通用的首部字段。因此,取值对客户端和服务器端含义会有所不一样。网络
应用 HTTP/1.1 版本的缓存服务器同时存在 Expires 首部字段的状况时,会优先处理 max-age 指令,而忽略 Expires 首部字段。
强缓存请求数据流程以下: 客户端向缓存服务器(缓存数据库)请求数据,若是有缓存数据且未失效,则返回数据。若是没有缓存数据或缓存数据失效,则向服务器请求数据,服务器返回数据和缓存规则,客户端收到并将数据和缓存规则存入缓存。
协商缓存的方式是客户端发送请求验证缓存标识所对应的数据是否失效,若是服务器判断数据有效,则返回一个 304 状态码(即报文首部和状态行),而不用返回报文主体。协议中规定了两种缓存标识。
Last-Modified/If-Modified-Since
客户端第一次请求服务器时,服务器在响应报文的首部经过 Last-Modified
字段告知浏览器资源的最后修改时间。
再次请求时,客户端在请求报文的首部添加 If-Modified-Since
字段,该字段的值是上次请求时,服务器返回的 Last-Modified
的值。
服务器收到请求发现有 If-Modified-Since 则与被请求资源的最后修改时间进行比对,若资源的最后修改时间大于 If-Modified-Since 所提供的值,说明资源被改动过,则响应资源内容,返回状态码 200。不然,说明资源没有被改动,则返回 304,告知浏览器可使用所保存的 cache。
Etag/If-None-Match 优先级高于 Last-Modified/If-Modified-Since
客户端第一次请求服务器时,服务器在响应报文的首部经过 Etag
字段告知浏览器当前资源在服务器的惟一标识(生成规则由服务器决定)。
同理,再次请求时,缓存数据的惟一标识被添加到请求报文的 If-None-Match
字段中。
服务器收到请求发现有 If-None-Match 则与被请求资源的惟一标识进行比对,不一样,说明资源被修改过,返回 200。相同,则说明资源未被修改,返回 304。
为何须要 Etag?
Etag 的出现是为了解决 Last-Modified/If-Modified-Since 比较难以解决的问题。好比:
因此,Etag 的优先级高于 Last-Modified 也是应该的。可是,性能上,Etag 要逊于 Last-Modified,由于 Last-Modified 指记录修改的时间值,而 Etag 的值须要算法计算一个 hash 值。
对于一下操做,如地址栏回车、页面连接跳转、新开窗口、前进和回退,两种机制( expires/validation )都是有效的。
F5 刷新操做,Expires/Cache-Control 是无效的,Last-Modified/Etag 是有效的,也就是说强制协商缓存。
Ctrl + F5 强制刷新,二者都是无效的。
抓包工具: Fiddler
查看 chrome 缓存
chrome://view-http-cache/
参考: 完全弄懂HTTP缓存机制及原理
应用缓存(application cache),简称 appcache,是专门为开发离线 Web 应用设计的。它是从浏览器的缓存中分出来的一块缓存区,使用一个 manifest
文件,列出要下载和缓存的资源。
第二步, 在须要离线使用的页面中添加 manifest 属性,用于指定缓存清单文件的路径。好比:
<html manifest="/offline.manifest">
复制代码
随着 Web 应用的出现,也产生了可以直接在客户端上存储用户信息能力的要求。
Cookie 是在客户端存储数据的其中一种选项。
Cookie 的工做机制是用户识别及状态管理。它是怎样工做的呢?好比,当要对某个用户进行识别的时候,服务器对任意的 HTTP 请求发送 Set-Cookie
首部字段做为响应的一部分。
HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: name=value
...
复制代码
这以后,浏览器的每一个请求都添加 Cookie
字段将信息发送回服务器。服务器就知道你是属于哪一个用户了。
GET /index.html HTTP/1.1
Cookie: name=value
...
复制代码
Set-Cookie 字段的属性
Cookie 字段只包含 Cookie
属性。该属性在请求中包含从服务器接收到的 Cookie,接收到多个 Cookie 时,一样能够以多个 Cookie 形式发送。
值得注意的时,为了避免会占据太多磁盘空间,每一个域的 cookie 总数有限的,不一样浏览器之间各有不一样。此外,对于 cookie 的尺寸也有限制。
另外,避免在 cookie 中存储敏感信息。
Web Storage 是 HTML5 的一部分,目的是克服由 cookie 带来的一些限制。
Web Storage 提供两种用于存储数据的对象,sessionStorage
对象和 localStorage
对象。
sessionStorage 对象存储特定于某个会话的数据,该数据只保持到浏览器关闭。存储在 sessionStorage 中的数据能够跨越页面刷新而存在。
另外,sessionStorage 对象应该主要用于仅针对会话的小段数据的存储。若是须要跨越会话存储数据,那么 localStorage 更合适。
存储在 localStorage 中的数据保留到经过 JavaScript 删除或者是用户清除浏览器缓存。同时,localStorage 支持同源策略。也就是说,要访问同一个 localStorage 对象,页面必须来自同一个域。
同理,和其余客户端存储方案相似,Web Storage 也有大小限制,因浏览器而异。
IndexedDB 是在浏览器中保存结构化数据的一种数据库。
参考: