缓存
可以说是性能优化
中最简单高效的一种方式,可以减低网络延迟,减小带宽等。
对于一个数据请求来说,可以分为网络请求、后端处理、浏览器响应三步,而缓存可以优化第一步和第三步,比如直接使用缓存不需要再发送请求,或者发了请求但后端存储的数据与缓存一致,就没有必要再把数据传送过来了。
浏览器缓存机制
- 浏览器发送请求前,都会根据请求头判断是否命中
强缓存策略
,如果命中,直接获取缓存的资源,不会发送请求。 - 没有命中
强缓存策略
,浏览器会发送请求,根据请求头中的Etag
和last-modified
判断是否命中协商缓存
,如果命中,直接获取缓存资源,否则获取服务器中的数据返回。
注: 图中仅表示判断的逻辑顺序,如果不带没些参数,可不进行判断
Cache Control (缓存规则)
服务端告诉浏览器此信息可不可以缓存,以什么样的策略进行缓存。
private
:浏览器可以缓存public
:浏览器和代理服务器可以缓存,因此我们中间层的服务节点,发现cache-control
的值为private
时,就认可只有发起请求的浏览器能够缓存,作为代理服务节点是不能够缓存的。如为public
时,代理服务器也可以缓存。max-age
单位 s 缓存到期时间no-store
不缓存请求的任何返回内容no-cache
会缓存请求返回的内容,在下次用缓存的内容时,需要向服务器验证一下,缓存到底能不能用
强缓存
如果资源没过期,直接获取缓存资源,过期了,再发送请求给服务器。
控制强制缓存
的字段分别是Expires
和Cache-Control
,其中Cache-Conctrol
的优先级比Expires
高,若同时使用前者会覆盖掉后者。
灰色 Status
状态码 200
是强缓存
from memory cache
: 内存中的缓存from disk cache
: 硬盘中的缓存
协商缓存
没有命中强制缓存,浏览器携带缓存标识(Etag
、last-modified
)向服务端发起请求,判断是否过期,没过期使用缓存,status 为304 not modified
。过期则返回服务器获取的数据,更新缓存。
200 OK
: Size
是数据大小的是获取服务器数据,没有实用缓存
为什么既有 last-modified 又有 Etag
- Etag 是文件的唯一标识,文件修改了标识就会变
- last-modified 记录最后一次修改的时间
- 有些文件会周期性更改,但内容无变化(仅时间改变),这个时候我们不希望客服端认为这个文件被修改了。
- 某些文件修改的过于频繁,低于 s 级,不能精确获得更改时间等
- 所以 Etag 可以更精确的控制缓存
Cookie
用于存储客户端的会话信息,记录状态(因为 http 是无状态的)。要求服务器在响应 http 请求时,通过发送Set-Cookie
HTTP 头部包含会话信息。浏览器会存储这些会话信息,并在之后的每个请求中都会通过 HTTP 头部 cookie 再将它们发送回服务器。Cookie
同源窗口共享的,浏览器关闭后就会清空。
Cookie 构成
name=value
;name=value
一个 cookie 以名/值对
形式存储,多个 cookie 之间以分号
分割。
JavaScript 中只能用 BOM 的document.cookie
属性来访问。
//document.cookie = "name=value"
document.cookie = "id=1;username=xxx";
可以自定义封装方法或者使用插件,如vue-cookie
,JQery-cookie
等
创建 cookie
document.cookie="username=Jom"
还可以为cookie
添加一个过期时间(以 UTC 或 GMT 时间)。默认情况下,cookie 在浏览器关闭时删除:
document.cookie="username=Jom; expires=Thu, 18 Dec 2021 12:00:00 GMT"
可以使用 path 参数告诉浏览器 cookie 的路径。默认情况下,cookie 属于当前页面
document.cookie="username=Jom; expires=Thu, 18 Dec 2021 12:00:00 GMT;path=/"
读取 cookie
var x = document.cookie;
//结果将会以字符串形式返回 id=1;username=Jom
修改 cookie 与添加相同,会覆盖掉原来的
删除 cookie,只需要设置 expires 为以前的时间即可
document.cookie="username=;expires=Thu, 01 Jan 1970 00:00:00 GMT";
Cookie 限制
- 与特定域绑定,只对认可的域接收,不被其他域访问
- 大小只有 4KB
- 所有
cookie
都会被作为请求头发送给服务器,所以若存储大量信息可能会影响浏览器请求的性能,所以尽可能只保留必要信息。 - 安全性:由于在 HTTP 请求中的
cookie
是明文传递的(HTTPS 不是),可能出现安全问题 - 所以为了更好的本地存储,使用
WebStorage
。Cookie
作为客户端与服务器交互的通道,保持客户端状态。
WebStorage
WebStorage
提供两种 API,localStorage
和sessionStorage
。两者有共同的 API。
- length: 唯一的属性,只读,用来获取 storage 内的键值对数量
- key:根据 index 获取 storage 的键名
- getItem:根据 key 获取 storage 内的对应 value
- setItem:为 storage 内添加键值对
- removeItem:根据键名,删除键值对
- clear:清空 storage 对象
localStorage 和 sessionStorage 区别
localStorage
本地永久存储,sessionStorage
存储的数据只在会话期间有效,关闭浏览器则自动删除。localStorage
支持同源窗口共享数据,sessionStorage
不支持。