体验一下什么是协商缓存

130 阅读2分钟

有很多文章都有从理论上讨论什么是协商缓存的,这里就不多做讲解了。这篇文章主要是要从实操入手协商缓存,给读者一个更直观的体验,以深刻理解什么是协商缓存。 原文地址:http://120.79.199.221:8090/archives/ti-yan-yi-xia-shen-me-shi-xie-shang-huan-cun

准备

首先用node建立一个简单的静态资源服务

const express = require("express");
const path = require('path')
const app = express();
const port = 3000;

app.use(
  "/",
  express.static(path.resolve("./static"), {
    lastModified: false,
    etag: true,
    setHeaders(res) {
      res.set("Cache-Control", "no-cache");
    }
  })
);
app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});

index.html页面放在static目录中,静态服务准备好后,使用node index.js启动。

首次访问

打开DevTools并访问http://localhost:3000/ 可以看到两个响应头:Cache-Control: no-cacheETag: W/"112-18170cbb3ef"

  • Cache-Control: no-cache: 告诉浏览器将返回的文件缓存起来,但下次访问时还是要询问服务器文件有没有更新
  • ETag: W/"112-18170cbb3ef": 返回文件的内容hash,下次重新请求该文件会将这个值带上

再次访问

刷新浏览器 可以看到发生了304重定向,这里的流程是因为服务器告诉浏览器的缓存策略是Cache-Control: no-cache,就算有缓存也询问下服务器对文件有没有做更新,下面看看它的请求头:

  • If-None-Match: 这个请求头带上上次返回的ETag值,服务器收到后进行比对,发现无变化就直接返回304状态告诉浏览器可以直接从缓存取

修改index.html

在index.html中随便改点儿啥,再刷新页面 可以看到状态码又是200了,看看它的请求头和响应头有什么不同? 可以发现请求头的If-None-Match的hash和响应头的ETag是不一样的。

总结

这里的协商缓存通过ETag / If-None-Match两个请求头/响应头去完成,有时候也会用Last-Modified / If-Modified-Since两个请求头/响应头去完成缓存的协商,如果同时出现的话,前者优先级大于后者