强缓存和协商缓存原理,及前端如何和服务端一同控制影响浏览器缓存,以及代码实战

1.强缓存(也称为本地缓存)和协商缓存是Web开发中用于优化页面加载性能的两种主要缓存机制。
  1. 强缓存:
    • 工作原理: 当客户端首次请求资源时,服务器会返回带有缓存控制信息的响应头,如Cache-Control或Expires。这些信息告诉客户端可以在一定时间内直接使用本地缓存而不需要向服务器发起请求。
    • Cache-Control: 使用max-age指定资源的最大缓存时间,例如Cache-Control: max-age=3600表示资源在3600秒内有效。
    • Expires: 指定资源的过期时间,是一个GMT格式的日期字符串,如Expires: Wed, 29 Feb 2024 12:00:00 GMT。
    • 优点: 加快页面加载速度,减轻服务器负担。
  2. 协商缓存:
    • 工作原理: 当客户端再次请求资源时,它会发送一个请求头,如If-Modified-Since或If-None-Match,携带上一次请求时服务器返回的相关信息。服务器根据这些信息判断是否需要返回新的资源,或者告诉客户端直接使用本地缓存。
    • Last-Modified: 服务器在响应头中返回资源的最后修改时间,客户端可通过If-Modified-Since发送上一次获取资源时的修改时间。
    • ETag: 服务器在响应头中返回资源的唯一标识,客户端可通过If-None-Match发送上一次获取资源时的标识。
    • 优点: 减少不必要的数据传输,提高服务器性能。
2.怎么使用

很多前端人看了这些东西,只知道原理,但是完全不知道如何去使用,下面我把强缓存和协商缓存的所有写法都列举出来,并附上相关的解释

1. 强缓存:
a. 使用 Cache-Control 字段的 no-store 指令,表示不缓存:
js 复制代码
fetch('/path/to/resource', {
  method: 'GET',
  headers: {
    'Cache-Control': 'no-store'
  }
})
  .then(response => response.text())
  .then(data => {
    // 处理获取到的数据
  })
  .catch(error => {
    console.error('Error:', error);
  });
b. 使用 Cache-Control 字段的 no-cache 指令,表示不直接使用缓存,需要向服务器验证:
js 复制代码
fetch('/path/to/resource', {
  method: 'GET',
  headers: {
    'Cache-Control': 'no-cache'
  }
})
  .then(response => response.text())
  .then(data => {
    // 处理获取到的数据
  })
  .catch(error => {
    console.error('Error:', error);
  });
c. 使用 Cache-Control 字段的 max-age 指令,设置缓存最大有效时间:
js 复制代码
fetch('/path/to/resource', {
  method: 'GET',
  headers: {
    'Cache-Control': 'max-age=3600' // 缓存1小时
  }
})
  .then(response => response.text())
  .then(data => {
    // 处理获取到的数据
  })
  .catch(error => {
    console.error('Error:', error);
  });
d. 使用 Expires 字段,设置缓存过期时间:
js 复制代码
fetch('/path/to/resource', {
  method: 'GET',
  headers: {
    'Expires': new Date(Date.now() + 3600000).toUTCString() // 缓存1小时
  }
})
  .then(response => response.text())
  .then(data => {
    // 处理获取到的数据
  })
  .catch(error => {
    console.error('Error:', error);
  });
2. 协商缓存:
a. 使用 If-None-Match 字段,携带上一次服务器返回的ETag值:
js 复制代码
fetch('/path/to/resource', {
  method: 'GET',
  headers: {
    'If-None-Match': 'previous-etag-value'
  }
})
  .then(response => {
    if (response.status === 304) {
      // 服务器返回 304 表示资源未被修改,可以使用缓存
      return getCachedData();
    } else {
      return response.text();
    }
  })
  .then(data => {
    // 处理获取到的数据
  })
  .catch(error => {
    console.error('Error:', error);
  });
b. 使用 If-Modified-Since 字段,携带上一次服务器返回的Last-Modified值:
js 复制代码
fetch('/path/to/resource', {
  method: 'GET',
  headers: {
    'If-Modified-Since': 'previous-last-modified-value'
  }
})
  .then(response => {
    if (response.status === 304) {
      // 服务器返回 304 表示资源未被修改,可以使用缓存
      return getCachedData();
    } else {
      return response.text();
    }
  })
  .then(data => {
    // 处理获取到的数据
  })
  .catch(error => {
    console.error('Error:', error);
  });
3.协商缓存使用的这些值,是如何判断他是不是要缓存呢

协商缓存是通过比较客户端发送的条件请求头(例如 If-None-Match 和 If-Modified-Since)与服务器上资源的相关信息来判断是否要返回新的资源还是告诉客户端继续使用缓存的一种机制。

  1. ETag(实体标签):
    • 服务器在响应头中生成一个唯一的标识符(通常是哈希值),称为ETag。
    • 当客户端再次请求资源时,它会携带上一次获取的ETag值,放在请求头的 If-None-Match 字段中。
    • 服务器比较客户端提供的ETag值与当前资源的ETag值,如果匹配,服务器返回状态码304,表示资源未被修改,可以使用缓存。

Last-Modified(最后修改时间):

  • 服务器在响应头中提供资源的最后修改时间。
  • 当客户端再次请求资源时,它会携带上一次获取的最后修改时间,放在请求头的 If-Modified-Since 字段中。
  • 服务器比较客户端提供的最后修改时间与当前资源的最后修改时间,如果客户端提供的时间早于资源的最后修改时间,服务器返回状态码304,表示资源未被修改,可以使用缓存。
总而言之,言而总之,这个缓存还是很复杂,只能从实际中慢慢去解析和进行开发了。
相关推荐
@大迁世界3 小时前
Firefox 本地模式:localhost 再见了 ?
前端·架构
米米商聊5 小时前
同名附件为什么被 Map 覆盖?重复键与一对多索引
前端·javascript
echome8886 小时前
Python 异常处理:try、else、finally 的正确搭配
开发语言·前端·python·异常处理·编程技巧
时间的情敌6 小时前
OpenLayers 实战|Vue3 + OpenLayers 完整工程案例(加载天地图、要素、弹窗、绘制、WFS)
前端·openlayers
陈随易6 小时前
下载神器!Motrix 停更三年后重写回归
前端·后端·程序员
前端的日常6 小时前
一个人+AI做情侣食谱小程序,0 费用的服务器
前端·后端
计算机魔术师7 小时前
谷歌搜索广告踩刹车,AI广告成为救命稻草
前端
总要学点什么7 小时前
第81篇:数据可视化-PM2.5分布——让圆点的胖瘦替每座城市报出浓度
前端·信息可视化·echarts·cesium·空间分析
IT_陈寒7 小时前
Vue的v-for里用了个临时变量,页面直接挂了
前端·人工智能·后端
hunter_0767 小时前
一次 iOS 真机签名 409 的完整排查:证书、设备、描述文件为什么总是"对不上"
前端