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

1.强缓存(也称为本地缓存)和协商缓存是Web开发中用于优化页面加载性能的两种主要缓存机制。
  1. 强缓存:
    • 工作原理: 当客户端首次请求资源时,服务器会返回带有缓存控制信息的响应头,如Cache-ControlExpires。这些信息告诉客户端可以在一定时间内直接使用本地缓存而不需要向服务器发起请求。
    • Cache-Control: 使用max-age指定资源的最大缓存时间,例如Cache-Control: max-age=3600表示资源在3600秒内有效。
    • Expires: 指定资源的过期时间,是一个GMT格式的日期字符串,如Expires: Wed, 29 Feb 2024 12:00:00 GMT
    • 优点: 加快页面加载速度,减轻服务器负担。
  2. 协商缓存:
    • 工作原理: 当客户端再次请求资源时,它会发送一个请求头,如If-Modified-SinceIf-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-MatchIf-Modified-Since)与服务器上资源的相关信息来判断是否要返回新的资源还是告诉客户端继续使用缓存的一种机制。

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

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

  • 服务器在响应头中提供资源的最后修改时间。
  • 当客户端再次请求资源时,它会携带上一次获取的最后修改时间,放在请求头的 If-Modified-Since 字段中。
  • 服务器比较客户端提供的最后修改时间与当前资源的最后修改时间,如果客户端提供的时间早于资源的最后修改时间,服务器返回状态码304,表示资源未被修改,可以使用缓存。
总而言之,言而总之,这个缓存还是很复杂,只能从实际中慢慢去解析和进行开发了。
相关推荐
Carlos_sam6 分钟前
OpenLayers:ol-wind之渲染风场图全解析
前端·javascript
拾光拾趣录15 分钟前
闭包:从“变量怎么还没死”到写出真正健壮的模块
前端·javascript
拾光拾趣录36 分钟前
for..in 和 Object.keys 的区别:从“遍历对象属性的坑”说起
前端·javascript
OpenTiny社区1 小时前
把 SearchBox 塞进项目,搜索转化率怒涨 400%?
前端·vue.js·github
编程猪猪侠1 小时前
Tailwind CSS 自定义工具类与主题配置指南
前端·css
qhd吴飞1 小时前
mybatis 差异更新法
java·前端·mybatis
YGY Webgis糕手之路2 小时前
OpenLayers 快速入门(九)Extent 介绍
前端·经验分享·笔记·vue·web
患得患失9492 小时前
【前端】【vueDevTools】使用 vueDevTools 插件并修改默认打开编辑器
前端·编辑器
ReturnTrue8682 小时前
Vue路由状态持久化方案,优雅实现记住表单历史搜索记录!
前端·vue.js
UncleKyrie2 小时前
一个浏览器插件帮你查看Figma设计稿代码图片和转码
前端