浏览器缓存机制
概念
浏览器缓存(Browser Caching)是浏览器端保存数据用于快速读取或避免重复资源请求的优化机制,有效的缓存使用可以避免重复的网络请求和浏览器快速地读取本地数据,整体上加速网页展示给用户。(浏览器缓存分为强缓存和协商缓存)
浏览器缓存机制要素:
- 浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识;
- 浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中。
九种浏览器缓存:
http 缓存
http 缓存是基于 HTTP 协议的浏览器文件级缓存机制。即针对文件的重复请求情况下,浏览器可以根据协议头判断从服务器端请求文件还是从本地读取文件。主要是针对重复的 http 请求,在有缓存的情况下判断过程主要分 3 步:判断 expires,如果未过期,直接读取 http 缓存文件,不发 http 请求,否则进入下一步;判断是否含有 etag,有则带上 if-none-match 发送请求,未修改返回 304,修改返回 200,否则进入下一步;判断是否含有 last-modified,有则带上 if-modified-since 发送请求,无效返回 200,有效返回 304,否则直接向服务器请求
websql
它是将数据以数据库的形式存储在客户端,根据需求去读取;跟 Storage 的区别是: Storage 和 Cookie 都是以键值对的形式存在的。
indexDB
IndexedDB 是一个为了能够在客户端存储可观数量的结构化数据,并且在这些数据上使用索引进行高性能检索的 API。同步 API 本来是要用于仅供 Web Workers 内部使用,但是还没有被任何浏览器所实现。异步 API 在 Web Workers 内部和外部都可以使用,另外浏览器可能对 indexDB 有 50M 大小的限制,一般用户保存大量用户数据并要求数据之间有搜索需要的场景。
Cookie
指一般网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。cookie 一般通过 http 请求中在头部一起发送到服务器端。一条 cookie 记录主要由键、值、域、过期时间、大小组成,一般用于保存用户的认证信息。cookie 最大长度和域名个数由不同浏览器决定。不同域名之间的 cookie 信息是独立的,如果需要设置共享可以在服务器端设置 cookie 的 path 和 domain 来实现共享。浏览器端也可以通过 document.cookie 来获取 cookie,并通过 js 浏览器端也可以方便地读取/设置 cookie 的值。(Cookie 只能存储少量的数据,每个 Cookie 的大小不超过 4KB。RFC 标准不允许浏览器保存超过 300 个 Cookie,为每个 web 服务器保存的 Cookie 数不超过 20 个。JavaScript 中使用 Cookie 不会采用任何加密机制,因此它们是不安全的。)
Localstorage
localStorage 是 html5 的一种新的本地缓存方案,目前用的比较多,一般用来存储 ajax 返回的数据,加快下次页面打开时的渲染速度。
Sessionstorage
sessionStorage 和 localstorage 类似,但是浏览器关闭则会全部删除,api 和 localstorage 相同,实际项目中使用较少。
application cache
application cahce 是将大部分图片资源、js、css 等静态资源放在 manifest 文件配置中。当页面打开时通过 manifest 文件来读取本地文件或是请求服务器文件。在线的情况下,浏览器发现 html 头部有 manifest 属性,它会请求 manifest 文件,如果是第一次访问 app,那么浏览器就会根据 manifest 文件的内容下载相应的资源并且进行离线存储。如果已经访问过 app 并且资源已经离线存储了,那么浏览器就会使用离线的资源加载页面,然后浏览器会对比新的 manifest 文件与旧的 manifest 文件,如果文件没有发生改变,就不做任何操作,如果文件改变了,那么就会重新下载文件中的资源并进行离线存储。并在下一次生效。离线的情况下,浏览器就直接使用离线存储的资源。
cacheStorage
CacheStorage 是在 ServiceWorker 的规范中定义的。CacheStorage 可以保存每个 serverWorker 申明的 cache 对象,cacheStorage 有 open、match、has、delete、keys 五个核心方法,可以对 cache 对象的不同匹配进行不同的响应。
flash 缓存
这种方式基本不用,这一方法主要基于 flash 有读写浏览器端本地目录的功能,同时也可以向 js 提供调用的 api,则页面可以通过 js 调用 flash 去读写特定的磁盘目录,达到本地数据缓存的目的。
cookie
- 背景:早期 Web 开发面临的最大问题之一是如何管理状态。简言之,服务器端没有办法知道两个请求是否来自于同一个浏览器。那时的办法是在请求的页面中插入一个 token,并且在下一次请求中将这个 token 返回(至服务器)。这就需要在 form 中插入一个包含 token 的隐藏表单域,或着在 URL 的 qurey 字符串中传递该 token。这两种办法都强调手工操作并且极易出错。
- 内容:键、值、域、过期时间、大小
- 是否生效:expires 指定了 cookie 何时不会再被发送到服务器端的,因此该 cookie 可能会被浏览器删掉。(过期时间)在没有 expires 选项时,cookie 的寿命仅限于单一的会话中。浏览器的关闭意味这一次会话的结束,所以会话 cookie 只存在于浏览器保持打开的状态之下。如果 expires 选项设置了一个过去的时间点,那么这个 cookie 会被立即删除。
- 存在哪里:cookie 的值被存储在名为 Cookie 的 HTTP 消息头中,并且只包含了 cookie 的值,其它的选项全部被去除。
- 存放形式:Cookies 是纯文本形式。几乎所有的实现方式都对 cookie 的值进行了一些列的 URL 编码(但不是必须)。原始的文档中指示仅有三种类型的字符必须进行编码:分号,逗号,和空格。
- 不同域名之间的 cookie 信息是独立的,不会冲突。浏览器会对 domain 的值与请求所要发送至的域名,做一个尾部比较(即从字符串的尾部开始比较),并且在匹配后发送一个 Cookie 消息头。domain 设置的值必须是发送 Set-Cookie 消息头的域名。与 domain 选项相同的是,path 指明了在发 Cookie 消息头之前必须在请求资源中存在一个 URL 路径。这个比较是通过将 path 属性值与请求的 URL 从头开始逐字符串比较完成的。如果字符匹配,则发送 Cookie 消息头。只有在 domain 选项核实完毕之后才会对 path 属性进行比较。path 属性的默认值是发送 Set-Cookie 消息头所对应的 URL 中的 path 部分。path 值越详细则 cookie 越靠前。domain-path 越详细则 cookie 字符串越靠前。可以通过设置 Cookie 的 path 属性来修改 Cookie 的作用域,如果把 path 设为“/”,就等同于让 Cookie 拥有了 localStorage 的作用域,即整个文档源。
- 默认情况下,Cookie 对于创建它的页面,以及与该页面同目录或子目录下的其他 web 页面可见。在 a.example.com 下的一个页面设置了 Cookie,将其 path 设为“/”,并将 domain 设为“.example.com”,这样该 Cookie 就对 example.com 域下的所有页面可见。
- 创建和存储 Cookie:对 Cookie 的所有操作都要通过读写 document 对象的 Cookie 属性来完成。Cookie 的值都是以键值对的形式存储。同样的,如果要设置 path、domain 等属性,只须以如下形式追加到 Cookie 值的后面: ;path=path
1 | //创建一个名字Cookie,同时设置它的过期时间 |
- 读取 Cookie:使用 document.cookie 可以获取到 Cookie 的值,不过这个值是一个字符串,为了更好地查看 Cookie 的值,往往会采用 split()方法将 Cookie 中的名值对分离出来。
1 | function getCookie() { |
Localstorage 和 sessionstorage
Localstorage 和 sessionstorage 是做什么的?localstorage 怎么清除它?在代码层面怎么清除?setitem 的是什么数据类型?getitem 的值是什么数据类型?
- 怎么清除
1 | localStorage.removeItem(key); //删除该域名下单条记录 |
- 存储格式:所有的数据都是以文本格式保存。其中 value 需为可转化为字符串的对象。localStorage 对象的键和值只能是字符串,假设我们要保存一个对象到 localStorage 中,可以使用拼接的方式。当然也可以借助 JSON 类,将对象转换成字符串保存,然后在取出来的时候将 json 字符串转换成真正可用的 json 对象格式
- 数据共享:不同浏览器无法共享 localStorage 或 sessionStorage 中的信息。相同浏览器的不同页面间可以共享相同的 localStorage(页面属于相同域名和端口),但是不同页面或标签页间无法共享 sessionStorage 的信息。