Open AlexZ33 opened 4 years ago
https://www.cnblogs.com/floor/p/9867194.html
公众号原文阅读:HTTP缓存机制
顾名思义,需要客户端跟服务器协商共同解决缓存问题。
协商缓存可使用的头组合有 Last-Modified/if-Modify-Since 和 ETag/if-None-Match
需要服务端手动处理判断请求头字段,以 node 部分代码为例: 1、Last-Modified/if-Modify-Since
// 获取 if-modified-since 这个请求头 const ifModifiedSince = req.headers['if-modified-since']; // 获取最后修改的时间 const lastModified = stat.ctime.toGMTString(); // 判断两者是否相等,如果相等返回304读取浏览器缓存。否则的话,重新发请求 if (ifModifiedSince === lastModified) { res.writeHead(304); res.end(); } else { res.setHeader('Content-Type', mime.getType(filepath)); res.setHeader('Last-Modified', stat.ctime.toGMTString()); // fs.createReadStream(filepath).pipe(res); }
//Etag 实体内容,他是根据文件内容,算出一个唯一的值。 let md5 = crypto.createHash('md5') let rs = fs.createReadStream(abs) let arr = []; // 你要先写入响应头再写入响应体 rs.on('data', function(chunk) { md5.update(chunk); arr.push(chunk) }) rs.on('end', function() { let etag = md5.digest('base64'); if(req.headers['if-none-match'] === etag) { console.log(req.headers['if-none-match']) res.statusCode = 304; res.end() return } res.setHeader('Etag', etag) // If-None-Match 和 Etag 是一对, If-None-Match是浏览器的, Etag是服务端的 res.end(Buffer.concat(arr)) })
浏览器在加载资源的时候,会先根据本地缓存资源的header中的信息(Expires 和 Cache-Control)来判断是否需要强制缓存。如果命中的话,则会直接使用缓存中的资源。否则的话,会继续向服务器发送请求。
关联的头字段有 Expires 和 Cache-Control
1、Expires
表示缓存到期时间,是 当前时间+缓存时间,浏览器在未过期之前不需要再次请求。 服务端代码以 nodejs 为例:
let { pathname } = url.parse(req.url, true); let abs = path.join(__dirname, pathname); res.setHeader('Expires', new Date(Date.now() + 20000).toGMTString()); fs.stat(path.join(__dirname, pathname), (err, stat) => { if(err) { res.statusCode = 404; res.end('not found') return } if(stat.isFile()) { fs.createReadStream(abs).pipe(res) } })
2、Cache-Control 键值列表
服务端代码 以 node 为例:
res.setHeader('Cache-Control', 'max-age=20')
res.setHeader('Cache-Control', 'no-store')
res.setHeader('Cache-Control', 'no-cache')
多个值用逗号分隔
res.setHeader('Cache-Control', 'public, max-age=1024')
注意:
禁止缓存应该使用 no-store 而不是 no-cache 指定 no-cache 或 max-age=0 表示客户端可以缓存资源,每次使用缓存资源前都必须重新验证其有效性。这意味着每次都会发起 HTTP 请求,但当缓存内容仍有效时可以跳过 HTTP 响应体的下载。这样既可以保证内容的有效性,又可以保证能获取到最新的内容。
深入理解浏览器的缓存机制 https://www.cnblogs.com/suihang/p/12855345.html
https://www.cnblogs.com/floor/p/9867194.html
公众号原文阅读:HTTP缓存机制![浏览器缓存思维笔记 (2)](https://user-images.githubusercontent.com/21971405/200994110-16a75832-0ee2-44d4-a4d5-a731e385c41b.png)
协商缓存
顾名思义,需要客户端跟服务器协商共同解决缓存问题。
协商缓存可使用的头组合有 Last-Modified/if-Modify-Since 和 ETag/if-None-Match
需要服务端手动处理判断请求头字段,以 node 部分代码为例: 1、Last-Modified/if-Modify-Since
强制缓存
浏览器在加载资源的时候,会先根据本地缓存资源的header中的信息(Expires 和 Cache-Control)来判断是否需要强制缓存。如果命中的话,则会直接使用缓存中的资源。否则的话,会继续向服务器发送请求。
关联的头字段有 Expires 和 Cache-Control
1、Expires
表示缓存到期时间,是 当前时间+缓存时间,浏览器在未过期之前不需要再次请求。 服务端代码以 nodejs 为例:
2、Cache-Control 键值列表![image](https://user-images.githubusercontent.com/21971405/229672120-c3fa565e-3238-4b8b-8813-0bc4e2811a54.png)
服务端代码 以 node 为例:
多个值用逗号分隔
注意:
禁止缓存应该使用 no-store 而不是 no-cache 指定 no-cache 或 max-age=0 表示客户端可以缓存资源,每次使用缓存资源前都必须重新验证其有效性。这意味着每次都会发起 HTTP 请求,但当缓存内容仍有效时可以跳过 HTTP 响应体的下载。这样既可以保证内容的有效性,又可以保证能获取到最新的内容。