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

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,表示资源未被修改,可以使用缓存。
总而言之,言而总之,这个缓存还是很复杂,只能从实际中慢慢去解析和进行开发了。
相关推荐
ShineWinsu10 小时前
对于Redis:RDB持久化的解析
linux·数据库·redis·缓存·面试·持久化·rdb
福兮说21 小时前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
郑州光合科技余经理1 天前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
小呆呆6661 天前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
Dovis(誓平步青云)1 天前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
hweiyu001 天前
Redis命令:HTTL
redis·缓存
码艺-Alimjan1 天前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js
可乐鸡翅yeah_1 天前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
IT_陈寒1 天前
Vite静态资源导入这个坑我帮你们踩过了
前端·人工智能·后端
广州华水科技1 天前
大坝安全监测解决方案:单北斗GNSS形变监测系统应用与维护
前端