浅谈http缓存使用(Cache-Control、Last-Modified、ETag使用)

简介: 浅谈http缓存使用(Cache-Control、Last-Modified、ETag使用)

目录


强缓存Cache-Control


创建一个简单的express服务器。

服务器端返回头设置Cache-Control。

max-age后是本地缓存的秒数。

import express from 'express'
import fs, { statSync } from 'fs'
const app = new express()
app.use(express.json())
//给app设置中间件,这样所有请求都会使用该缓存。
app.use((req, res, next) => {
    res.set({
        'Cache-Control': 'max-age=2', 
    })
    next()
})
app.get('/getName', (req, res) => {
    res.send({
        name: '名字'
    })
})
app.listen(3000, () => {
    console.log('服务启动!')
})

浏览器审查时,重复请求,会发现被强缓存在本地的2秒内都会disk cache从本地缓存请求。

2秒缓存过期后便会重新像服务器发送请求。

image.png

image.png

协商缓存



协商缓存一般在强缓存之后,每当强缓存过期,再次请求时将会去服务器请求。


此时请求头会生成一个与响应头对应的属性,来验证文件是否修改。


如若修改则返回最新文件,未修改则返回304不反回包体,提示浏览器继续使用原来保存的缓存。


协商缓存有两种。


第一种 Last-Modified和If-Modified-Since



我们保留两秒的强缓存,加上Last-Modified,即文件的最后修改时间戳。

app.use((req, res, next) => {
    const stat = fs.statSync('./app.js')
    const { mtime } = stat
    res.set({
        'Cache-Control': 'max-age=2', 
        'Last-Modified': mtime.toUTCString(), 
    })
    next()
})

当浏览器每次去服务器请求,会将响应头的Last-Modified记录,也就是浏览器进行下一次请求时,能够知道上次的Last-Modified,记得上次服务端文件的修改时间。


这意味着什么呢?


连续请求时,首先会进行强缓存,2s缓存过期后,去服务器时,请求头会自动带上If-Modified-Since,这个字段也就是上次请求响应头中的Last-Modified。


此时响应头仍然有一个Last-Modified最后修改时间,而请求头的If-Modified-Since是上次请求返回的最后修改时间,会对这两个值进行对比。


若是在该请求之前,服务器文件被修改过了,Last-Modified则更新了,会比If-Modified-Since时间更新,则表示请求文件被修改了,否则未修改。


未修改则返回304,表示浏览器可继续用原来的缓存内容。


这里用火狐浏览器测试,因为谷歌浏览器确实是协商缓存,但是它并不能显示304。


2秒强缓存结束,就会进行协商缓存,发现文件未改变,返回304继续读取缓存。


image.png

我们修改一下服务器文件并重启,再请求一次。

此时文件被修改,返回了323个字节,没有从缓存读取。

image.png

让我们看一看304的协商字段和最新的协商字段

image.png

image.png

第二种 ETag和If-None-Match



ETag代替了Last-Modified作为文件最后的标识,是一个随机生成的字符串。


If-None-Match会记录上次请求获取的ETag。


因为ETag缓存默认存在,不知道是不是express服务器默认携带,因此我们可以将Last-Modified注释,用火狐继续测试。


ETag优先级比Last-Modified高。

app.use((req, res, next) => {
    // const stat = fs.statSync('./app.js')
    // const { mtime } = stat
    res.set({
        'Cache-Control': 'max-age=2', 
        // 'Last-Modified': mtime.toUTCString(), 
    })
    next()
})

注释掉了仍然会存在304,也就是协商缓存,就是ETag在起作用。

image.png

我们也修改一次文件,最好就修改返回内容,因为ETag与Last-Modified不同,返回内容不变的话,ETag知道文件修改了等于没修改不会改变。

image.png

查看两次不同。

image.png

image.png

为什么有了Last-Modified还需要ETag?

  1. 因为Last-Modified毕竟是时间戳只能精确到秒级,万一存在1s内多次修改怎么办?
  2. 文件修改了,但是内容没有变动,也会导致Last-Modified更新,此时没达到使用缓存的目的。
  3. 时间戳获取不一定精准。
相关文章
|
8月前
|
存储 缓存 安全
第二章 HTTP请求方法、状态码详解与缓存机制解析
第二章 HTTP请求方法、状态码详解与缓存机制解析
150 0
|
8月前
|
存储 缓存 前端开发
HTTP的缓存机制是什么?
HTTP的缓存机制是什么?
112 1
|
8月前
|
缓存
HTTP 请求头Cache-Control 详解
HTTP 请求头Cache-Control 详解
460 0
|
5月前
|
缓存 JSON 前端开发
超详细讲解:http强缓存和协商缓存
超详细讲解:http强缓存和协商缓存
|
3月前
|
存储 缓存 NoSQL
保持HTTP会话状态:缓存策略与实践
保持HTTP会话状态:缓存策略与实践
|
3月前
|
存储 缓存 监控
HTTP:强缓存优化实践
HTTP强缓存是提升网站性能的关键技术之一。通过精心设计缓存策略,不仅可以显著减少网络延迟,还能降低服务器负载,提升用户体验。实施上述最佳实践,结合持续的监控与调整,能够确保缓存机制高效且稳定地服务于网站性能优化目标。
62 3
|
7月前
|
缓存 负载均衡 NoSQL
Redis系列学习文章分享---第十四篇(Redis多级缓存--封装Http请求+向tomcat发送http请求+根据商品id对tomcat集群负载均衡)
Redis系列学习文章分享---第十四篇(Redis多级缓存--封装Http请求+向tomcat发送http请求+根据商品id对tomcat集群负载均衡)
94 1
|
7月前
|
域名解析 存储 缓存
HTTP请求流程概览:浏览器构建请求行含方法、URL和版本;检查缓存;解析IP与端口
【6月更文挑战第23天】 HTTP请求流程概览:浏览器构建请求行含方法、URL和版本;检查缓存;解析IP与端口;TCP连接(HTTP/1.1可能需排队);三次握手;发送请求头与体;服务器处理并返回响应;TCP连接可能关闭或保持;浏览器接收并显示响应,更新缓存。HTTP版本间有差异。
116 5
|
6月前
|
缓存 JSON 算法
http【详解】状态码,方法,接口设计 —— RestfuI API,头部 —— headers,缓存
http【详解】状态码,方法,接口设计 —— RestfuI API,头部 —— headers,缓存
98 0
|
8月前
|
存储 缓存 前端开发
http缓存机制
HTTP缓存机制通过缓存控制头、实体标签和最后修改时间头优化Web性能,减少网络请求。Cache-Control指令如`public`, `private`, `max-age`, `no-cache`, `no-store`管理缓存行为。ETag用于验证资源完整性,Last-Modified检查资源是否更新。前端可利用Web存储和服务工作者进行细粒度缓存控制。正确配置缓存关键在于适应应用场景和需求。