Web缓存知多少(缓存机制和数据存储)

Web 缓存有不少种,好比数据库缓存、代理服务器缓存、CDN 缓存,以及浏览器缓存。html

浏览器缓存指的是将缓存文件保存在客户端,通常是经过 HTTP 进行缓存。算法

HTTP 缓存机制

HTTP/1.1 标准中固定了 HTTP 缓存的两种方式: expiration 机制 和 validation 机制。前者是经过减小服务器和浏览器的循环次数,后者经过只响应头部信息较少网络带宽。(有些参考资料,将前者称为强缓存,后者称为协商缓存)chrome

强缓存优先级高于协商缓存,也就是说,当执行强缓存的规则,缓存生效,则再也不执行协商缓存。数据库

expiration Model -- 强缓存

expiration 机制经过 ExpiresCache-Control 两个字段来标明失效规则。浏览器

Expires缓存

Expires 的值为服务器返回的到期时间,即下一次请求时,请求时间小于服务器返回的到期时间,直接使用缓存数据。可是因为客户端和服务器可能有时间差,会致使较大的缓存命中偏差,因此 HTTP/1.1 使用了 Cache-Control 替代。安全

Cache-Control服务器

Cache-Control 是很是重要的规则。取值以下:cookie

  • private: 默认取值,表示客户端能够缓存
  • public: 客户端和代理服务器均可以缓存
  • max-age: 缓存内容会在 xxx 秒后失效
  • no-cache: 缓存前确认必须先确认其有效性
  • no-store: 全部内容都不会缓存

注意,Cache-Control 是一个通用的首部字段。因此,取值对客户端和服务器端含义会有所不一样。网络

应用 HTTP/1.1 版本的缓存服务器同时存在 Expires 首部字段的状况时,会优先处理 max-age 指令,而忽略 Expires 首部字段。

强缓存请求数据流程以下: 客户端向缓存服务器(缓存数据库)请求数据,若是有缓存数据且未失效,则返回数据。若是没有缓存数据或缓存数据失效,则向服务器请求数据,服务器返回数据和缓存规则,客户端收到并将数据和缓存规则存入缓存。

validation Model -- 协商缓存

协商缓存的方式是客户端发送请求验证缓存标识所对应的数据是否失效,若是服务器判断数据有效,则返回一个 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 比较难以解决的问题。好比:

  • 一些文件会周期性地更改,可是内容并不会改变,只是改变修改时间,这个时候咱们不太须要客户端认为文件内容被修改过了,而请求资源
  • 某些文件修改很是频繁(指的是内容),好比每秒以内修改了屡次,If-Modified-Since 能检查到的粒度是秒级,这种修改可能致使没法断定。

因此,Etag 的优先级高于 Last-Modified 也是应该的。可是,性能上,Etag 要逊于 Last-Modified,由于 Last-Modified 指记录修改的时间值,而 Etag 的值须要算法计算一个 hash 值。

HTTP 缓存过程总结

  1. 浏览器第一次加载资源,服务器返回 200,并将数据和缓存规则存入缓存。
  2. 再次请求资源时,若是当前时间和上一次返回 200 的时间差不超过 Cache-Control 设置的 max-age,则没有过时,命中缓存(若是浏览器不支持 HTTP/1.1,则用 expires 判断是否过时)。若是时间过时,则向服务器发送 If-None-Match 和 If-Modified-Since 请求。
  3. 服务器收到请求,首先根据 Etag 的值判断被请求的文件有没有被修改,Etag 值一致,则命中协商缓存,返回304;若是不一致,返回新的资源的缓存规则和状态码,并返回 200。
  4. 若是服务器收到的请求没有 Etag 值,则将 If-Modified-Since 和被请求的文件的最后修改时间作对比,一致则命中协商缓存,返回 304;不然返回新的 Last-Modified 和数据,返回 200。

用户操做对缓存的影响

对于一下操做,如地址栏回车、页面连接跳转、新开窗口、前进和回退,两种机制( expires/validation )都是有效的。

F5 刷新操做,Expires/Cache-Control 是无效的,Last-Modified/Etag 是有效的,也就是说强制协商缓存。

Ctrl + F5 强制刷新,二者都是无效的。

抓包工具: Fiddler

查看 chrome 缓存 chrome://view-http-cache/

参考: 完全弄懂HTTP缓存机制及原理


HTML5 应用缓存

应用缓存(application cache),简称 appcache,是专门为开发离线 Web 应用设计的。它是从浏览器的缓存中分出来的一块缓存区,使用一个 manifest 文件,列出要下载和缓存的资源。

第二步, 在须要离线使用的页面中添加 manifest 属性,用于指定缓存清单文件的路径。好比:

<html manifest="/offline.manifest">
复制代码

数据存储

随着 Web 应用的出现,也产生了可以直接在客户端上存储用户信息能力的要求。

Cookie 是在客户端存储数据的其中一种选项。

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 字段的属性

  • name 名称 一个惟一肯定的 cookie 的名称,名称必须被 URL 编码
  • value 值 存储在 cookie 中的字符串的值。值必须被 URL 编码
  • domain 域名 肯定 cookie 有效的域,全部向该域发送的请求中都包含这个 cookie 信息
  • path 路径 对于制定域中的那个路径,才应该向服务器发送 cookie
  • expire 失效时间
  • secure 安全标识 指定后,cookie 只能在使用 SSL 链接时(即HTTPS通讯时)才发送到服务器
  • HttpOnly 它使得附加在 HttpOnly 属性后的 Cookie 内容没法被 JavaScript 读取,能够防止 XSS 攻击

Cookie 字段只包含 Cookie 属性。该属性在请求中包含从服务器接收到的 Cookie,接收到多个 Cookie 时,一样能够以多个 Cookie 形式发送。

值得注意的时,为了避免会占据太多磁盘空间,每一个域的 cookie 总数有限的,不一样浏览器之间各有不一样。此外,对于 cookie 的尺寸也有限制。

另外,避免在 cookie 中存储敏感信息。

Web Storage

Web Storage 是 HTML5 的一部分,目的是克服由 cookie 带来的一些限制。

  • 提供一种在 cookie 以外存储会话数据的途径
  • 提供一种存储大量能够跨会话存在的数据的机制

Web Storage 提供两种用于存储数据的对象,sessionStorage 对象和 localStorage 对象。

sessionStorage

sessionStorage 对象存储特定于某个会话的数据,该数据只保持到浏览器关闭。存储在 sessionStorage 中的数据能够跨越页面刷新而存在。

另外,sessionStorage 对象应该主要用于仅针对会话的小段数据的存储。若是须要跨越会话存储数据,那么 localStorage 更合适。

localStorage

存储在 localStorage 中的数据保留到经过 JavaScript 删除或者是用户清除浏览器缓存。同时,localStorage 支持同源策略。也就是说,要访问同一个 localStorage 对象,页面必须来自同一个域。

同理,和其余客户端存储方案相似,Web Storage 也有大小限制,因浏览器而异。

IndexedDB

IndexedDB 是在浏览器中保存结构化数据的一种数据库。

参考:

相关文章
相关标签/搜索