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

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,表示资源未被修改,可以使用缓存。
总而言之,言而总之,这个缓存还是很复杂,只能从实际中慢慢去解析和进行开发了。
相关推荐
腾讯TNTWeb前端团队6 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰9 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪9 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪10 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy10 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom11 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom11 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom11 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom11 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom11 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试