浏览器缓存

105 阅读2分钟

「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」。

一、前言

浏览器缓存一般是Http请求的缓存的机制,主要分为强缓存和协商缓存。

二、缓存的设置

  • 强缓存

我们可以通过设置ExpiresCache-control来设置,其中Cache-Control的优先级比Expires高。

1. Expires

res.setHeader('Expires', new Date(Date.now() + 10 * 1000).toGMTString())

image.png 我们看到设置的Expires是绝对时间,如果修改本地时间,可能会造成缓存失效。

2. Cache-control

res.setHeader('Cache-control', 'max-age=10)

image.png Cache-control设置的是相对时间,max-age设置的单位是秒。

对于Cache-control还有一些其他设置publicprivateno-cacheno-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 image.png

我们看下浏览器对资源的请求:

首先第一次请求资源时,在Response Headers里面带有Last-Modified给客户端,最后的修改时间。 image.png

我们刷新页面,在下一次去请求这个资源的时候,我们看到在Request Headers中加上了If-Modified-Since,服务器会根据这个值和Last-Modified进行对比,然后两个相等,返回一个空和304的状态码,你去缓存里面去找。

image.png

然后我们修改文件,再看

image.png 两个值不相等,说明文件有更新,这时会返回新的资源,状态码是200。

但是,这种设置会有缺点

  • 如果文件没有改变,修改时间变了(即,我改了一个东西,然后又把它改回去了),也会重新发送请求。
  • 因为 Last-Modified 精确到秒的,如果在这一秒内修改了资源,也会造成不会请求到新的资源的问题。

2. ETag和If-None-Match

我们通过文件来生成一个标识(比如用MD5)来判断文件是否修改了。

它的过程和Last-Modified差不多,只不过是根据文件内容来生成一个标识。

缺点

  • 通过文件内容生成hash会消耗一定的性能。