前端缓存
什么是 web 缓存(前端缓存)
web 缓存主要指的是两部分:浏览器缓存和 http 缓存
浏览器缓存:比如,localStorage,sessionStorage,cookie 等等。这些功能主要用于缓存一些必要的数据,比如用户信息。比如需要携带到后端的参数。亦或者是一些列表数据等等。比较基础,不做过多赘述。
http 缓存
缓存可以解决什么问题?他的缺点是什么?
先说说,缓存可以解决什么问题。
- 减少不必要的网络传输,节约宽带(就是省钱)
- 更快的加载页面(就是加速)
- 减少服务器负载,避免服务器过载的情况出现。(就是减载)
再说说缺点
- 占内存(有些缓存会被存到内存中)
http 缓存分为强制缓存与协商缓存
强制缓存
强制缓存,我们简称强缓存。
从强制缓存的角度触发,如果浏览器判断请求的目标资源有效命中强缓存,如果命中,则可以直接从内存中读取目标资源,无需与服务器做任何通讯
基于 Expires 字段实现的强缓存
过时了,有缺陷,略
基于 Cache-control 实现的强缓存(代替 Expires 的强缓存实现方法)
Cache-control
这个字段在 http1.1 中被增加,Cache-control
完美解决了 Expires
本地时间和服务器时间不同步的问题。是当下的项目中实现强缓存的最常规方法。
用法
//往响应头中写入需要缓存的时间
res.writeHead(200, {'Cache-Control': 'max-age=10',
})
Cache-Control:max-age=N,N 就是需要缓存的秒数。从第一次请求资源的时候开始,往后 N 秒内,资源若再次请求,则直接从磁盘(或内存中读取),不与服务器做任何交互。
Cache-control 有 max-age、s-maxage、no-cache、no-store、private、public 这六个属性。
属性 | 作用 |
---|---|
max-age | 决定客户端资源被缓存多久。 |
s-maxage | 决定代理服务器缓存的时长。 |
no-cache | 表示是强制进行协商缓存。 |
no-store | 是表示禁止任何缓存策略。 |
public | 表示资源即可以被浏览器缓存也可以被代理服务器缓存。 |
private | 表示资源只能被浏览器缓存。 |
no_cache
是 Cache-control
的一个属性。它并不像字面意思一样禁止缓存,实际上,no-cache
的意思是强制进行协商缓存。如果某一资源的 Cache-control
中设置了 no-cache
,那么该资源会直接跳过强缓存的校验,直接去服务器进行协商缓存。而 no-store
就是禁止所有的缓存策略了。
作者:工边页字
链接:https://juejin.cn/post/7127194919235485733
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
注意,no-cache 和 no-store 是一组互斥属性,这两个属性不能同时出现在 Cache-Control 中。
在一般的项目架构中 max-age 就够用。
而 s-maxage 因为是代理服务端的缓存时长,他必须和上面说的 public 属性一起使用(public 属性表示资源可以在代理服务器中缓存)。
Cache-control 如何设置多个值:
;`Cache-control:max-age=10000,s-maxage=200000,public`
协商缓存
协商缓存分两种:last-modified 和 ETag
基于 last-modified 的协商缓存
- 首先需要在服务器端读出文件修改时间,
- 将读出来的修改时间赋给响应头的 last-modified 字段。
- 最后设置 Cache-control:no-cache
当客户端读取到 last-modified 的时候,会在下次的请求标头中携带一个字段:If-Modified-Since。
那么之后每次对该资源的请求,都会带上 If-Modified-Since 这个字段,而务端就需要拿到这个时间并再次读取该资源的修改时间,让他们两个做一个比对来决定是读取缓存还是返回新的资源
基础 ETag 的协商缓存
ETag 就是将原先协商缓存的比较时间戳的形式修改成了比较文件指纹。
- 第一次请求某资源的时候,服务端读取文件并计算出文件指纹,将文件指纹放在响应头的 etag 字段中跟资源一起返回给客户端。
- 第二次请求某资源的时候,客户端自动从缓存中读取出上一次服务端返回的 ETag 也就是文件指纹。并赋给请求头的 if-None-Match 字段,让上一次的文件指纹跟随请求一起回到服务端。
- 服务端拿到请求头中的 is-None-Match 字段值(也就是上一次的文件指纹),并再次读取目标资源并生成文件指纹,两个指纹做对比。如果两个文件指纹完全吻合,说明文件没有被改变,则直接返回 304 状态码和一个空的响应体并 return。如果两个文件指纹不吻合,则说明文件被更改,那么将新的文件指纹重新存储到响应头的 ETag 中并返回给客户端
指纹完全吻合,说明文件没有被改变,则直接返回 304 状态码和一个空的响应体并 return。如果两个文件指纹不吻合,则说明文件被更改,那么将新的文件指纹重新存储到响应头的 ETag 中并返回给客户端