「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」。
一、前言
浏览器缓存一般是Http请求的缓存的机制,主要分为强缓存和协商缓存。
二、缓存的设置
-
强缓存
我们可以通过设置Expires和Cache-control来设置,其中Cache-Control的优先级比Expires高。
1. Expires
res.setHeader('Expires', new Date(Date.now() + 10 * 1000).toGMTString())
我们看到设置的
Expires是绝对时间,如果修改本地时间,可能会造成缓存失效。
2. Cache-control
res.setHeader('Cache-control', 'max-age=10)
Cache-control设置的是相对时间,max-age设置的单位是秒。
对于Cache-control还有一些其他设置public、private、no-cache、no-store等。
res.setHeader('Cache-control', 'no-cache') // 缓存,但是每次都会发送请求
res.setHeader('Cache-control', 'no-store') // 不在浏览器中进行缓存,每次都要向服务器发送请求
总结
强制缓存的状态码是200,不会向服务器发送请求,直接从浏览器缓存中读取。我们可以通过设置请求过期时间来进行缓存。(在这里我们需要注意一下,我们默认访问的那个页面是不会缓存的。)
-
协商缓存
协商缓存是浏览器携带标识请求给服务器,服务器根据标识判断是否使用缓存。我们通过设置Last-Modified和If-Modified-Since以及ETag和If-None-Match来看。
1. Last-Modified和If-Modified-Since
我们看下浏览器对资源的请求:
首先第一次请求资源时,在Response Headers里面带有Last-Modified给客户端,最后的修改时间。
我们刷新页面,在下一次去请求这个资源的时候,我们看到在Request Headers中加上了If-Modified-Since,服务器会根据这个值和Last-Modified进行对比,然后两个相等,返回一个空和304的状态码,你去缓存里面去找。
然后我们修改文件,再看
两个值不相等,说明文件有更新,这时会返回新的资源,状态码是200。
但是,这种设置会有缺点
- 如果文件没有改变,修改时间变了(即,我改了一个东西,然后又把它改回去了),也会重新发送请求。
- 因为
Last-Modified精确到秒的,如果在这一秒内修改了资源,也会造成不会请求到新的资源的问题。
2. ETag和If-None-Match
我们通过文件来生成一个标识(比如用MD5)来判断文件是否修改了。
它的过程和Last-Modified差不多,只不过是根据文件内容来生成一个标识。
缺点
- 通过文件内容生成hash会消耗一定的性能。