前端浏览器缓存

浏览器缓存:缓存协商(协商缓存)和彻底缓存(强缓存)

1、强制缓存:不会向服务器发送请求,直接从缓存中读取资源,在chrome控制台的network选项中可以看到该请求返回200的状态码。

2、协商缓存:在使用本地缓存之前,需要向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源;协商缓存可以解决强制缓存的情况下,资源不更新的问题。

两者的共同特点:都是从客户端缓存中读取资源,区别是强缓存不会发请求,协商缓存会发请求。 

强制缓存中header的参数(响应头)

Expires:response header里的过期时间,浏览器再次加载资源时,如果在这个过期时间内则命中强缓存。

Cache-Control:当值设为max-age=300时,则代表在这个请求正确返回时间(浏览器也会记录下来)的五分钟内再次加载资源,则会命中强缓存。

Cache-Control:

  • 在 Response Headers 中。
  • 控制强制缓存的逻辑。
  • 例如 Cache-Control: max-age=3153600(单位是秒)

Cache-Control 有哪些值:

  • max-age:缓存最大过期时间。
  • no-cache:可以在客户端存储资源,每次都必须去服务端做新鲜度校验,来决定从服务端获取新的资源(200)还是使用客户端缓存(304)。
  • no-store:永远都不要在客户端存储资源,永远都去原始服务器去获取资源。
function send(req, res, filepath) {
  res.setHeader('Content-Type', mime.getType(filepath))
  res.setHeader('Expires', new Date(Date.now() + 30 * 1000).toUTCString())
  res.setHeader('Cache-Control', 'max-age=30')
  fs.createWriteStream(filepath).pipe(res)
}
协商缓存中header的参数(响应头)
  • Last-Modified:资源的最后修改时间。
  • Etag:资源的唯一标识(一个字符串,类似于人类的指纹)。​​​​​​​

服务端拿到 if-Modified-Since 之后拿这个时间去和服务端资源最后修改时间做比较,如果一致则返回 304 ,不一致(也就是资源已经更新了)就返回 200 和新的资源及新的 Last-Modified。 

其实 Etag 和 Last-Modified 一样的,只不过 Etag 是服务端对资源按照一定方式(比如 contenthash)计算出来的唯一标识,就像人类指纹一样,传给客户端之后,客户端再传过来时候,服务端会将其与现在的资源计算出来的唯一标识做比较,一致则返回 304,不一致就返回 200 和新的资源及新的 Etag。

两者比较

  • 优先使用 Etag。
  • Last-Modified 只能精确到秒级。
  • 如果资源被重复生成,而内容不变,则 Etag 更精确。
    const http = require('http')
    const url = require('url')
    const path = require('path')
    const { stat, readFile } = require('fs/promises')
    const crypto = require('crypto')
    // stat 读取路径
    http
      .createServer(async (req, res) => {
        let { pathname } = url.parse(req.url)
        // console.log(pathname)
        // console.log(path.join(__dirname, '../', pathname, 'static/index.html'))
        let fileName =
          pathname === '/'
            ? path.join(__dirname, '../', pathname, 'static/index.html')
            : path.join(__dirname, '../', pathname)
        // console.log(fileName)
        try {
          const statObj = await stat(fileName)
          console.log(statObj.ctime)
          // 协商缓存
          /**
           * Last-Modified/If-Modified-Since和Etag/If-None-Match,其中Etag/If-None-Match的优先级比Last-Modified / If-Modified-Since高。
           */
          /*
            atime 创建时间
            mtime 修改时间 
            ctime 任何东西
          */
    
           const ctime = statObj.ctime.toGMTString()
           res.setHeader('Last-Modified', ctime) // 根据秒的方式
           if (req.headers['if-modified-since'] === ctime) {
             return (res.statusCode = 304) && res.end()
           }

  • 17
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值