当前位置: 首页 > news >正文

【代码优化篇】强缓存和协商缓存

强缓存和协商缓存

      • 一、强缓存与协商缓存的区别
      • 二、Vue2 前端实现强缓存(静态资源)
      • 三、Spring Boot 后端实现协商缓存(动态接口)
      • 四、测试缓存效果
      • 五、注意事项

一、强缓存与协商缓存的区别

强缓存:浏览器直接读取本地缓存,不发送请求到服务器。通过 Cache-ControlExpires 响应头实现。
协商缓存:浏览器发送请求到服务器,由服务器判断资源是否过期。通过 ETag/If-None-MatchLast-Modified/If-Modified-Since 实现。


二、Vue2 前端实现强缓存(静态资源)

步骤

  1. 打包生成哈希文件名:Vue2 默认在 webpack 配置中为文件名添加 contenthash,如 app.a1b2c3.js
  2. 服务器配置强缓存头:在 Nginx/CDN 中为静态资源设置 Cache-Control: max-age=31536000(1年)。

示例 Nginx 配置

location /static {alias /path/to/static;expires 1y; # 等效于 Cache-Control: max-age=31536000add_header Cache-Control "public";
}

三、Spring Boot 后端实现协商缓存(动态接口)

步骤

  1. 添加 ETag 支持:使用 ShallowEtagHeaderFilter 自动生成 ETag。
  2. 返回带缓存控制的响应:手动设置 Cache-Control 头。

示例代码

import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.ShallowEtagHeaderFilter;
import org.springframework.http.CacheControl;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.Filter;
import java.util.concurrent.TimeUnit;@Configuration
public class WebConfig {public Filter etagFilter() {return new ShallowEtagHeaderFilter();}
}@RestController
public class ApiController {// 协商缓存示例(自动 ETag)@GetMapping("/user")public ResponseEntity<User> getUser() {User user = userService.findUser();return ResponseEntity.ok().cacheControl(CacheControl.maxAge(30, TimeUnit.MINUTES)) // 建议缓存但需要验证.body(user);}// 强缓存示例(慎用)@GetMapping("/static-data")public ResponseEntity<String> getStaticData() {return ResponseEntity.ok().cacheControl(CacheControl.maxAge(7, TimeUnit.DAYS)) // 强缓存7天.body("Immutable Data");}
}

四、测试缓存效果

  1. 强缓存

    • 首次请求:返回 200 OK,响应头包含 Cache-Control: max-age=31536000
    • 再次请求:浏览器直接读取缓存,状态为 200 (from disk cache)
  2. 协商缓存

    • 首次请求:返回 200 OK,响应头包含 ETag: "a1b2c3"
    • 再次请求:请求头携带 If-None-Match: "a1b2c3",若未修改,服务器返回 304 Not Modified

五、注意事项

  • 前端静态资源:确保文件名哈希变化,避免旧缓存影响新版本。
  • 动态接口:敏感数据避免使用强缓存,优先用 no-cacheprivate
  • 测试工具:使用浏览器开发者工具的 Network 面板检查响应头与缓存状态。

总结:强缓存通过设置长时间 max-age 实现,适用于静态资源;协商缓存通过 ETag/Last-Modified 验证,适用于动态数据。Vue2 利用打包哈希 + 服务器配置,Spring Boot 通过响应头控制实现。

在这里插入图片描述

相关文章:

  • 数据结构--二叉树
  • 【wpf】10 C#树形控件高效实现:递归构建与路径查找优化详解
  • SSHv2 密钥交换(Key Exchange)详解
  • 低空科技护航珞樱春色,技术引领助推广阔应用
  • 代码随想录图论part4
  • 白杨SEO:如何查看百度、抖音、微信、微博、小红书、知乎、B站、视频号、快手等7天内最热门话题及流量关键词有哪些?使用方法和免费工具推荐以及注意事项【干货】
  • 【计算机网络-传输层】传输层协议-UDP
  • 【解决】VsCode C++异常【terminate called after throwing an instance of ‘char const‘】
  • Umi+React+Xrender+Hsf项目开发总结
  • Python引领前后端创新变革,重塑数字世界架构
  • vscode预览模式(点击文件时默认覆盖当前标签,标签名称显示为斜体,可通过双击该标签取消)覆盖标签、新窗打开
  • Redis再次开源!reids8.0.0一键安装脚本分享
  • Web前端技术栈:从入门到进阶都需要学什么内容
  • string--OJ3
  • 数据智能重塑工业控制:神经网络在 MPC 中的四大落地范式与避坑指南
  • 学习笔记:黑马程序员JavaWeb开发教程(2025.3.29)
  • 第16章 Python数据类型详解:列表(List)与运维开发实践
  • Cloudera CDP 7.1.3 主机异常关机导致元数据丢失,node不能与CM通信
  • 大数据技术全景解析:Spark、Hadoop、Hive与SQL的协作与实战
  • Qt开发经验:回调函数的线程归属问题及回调函数中更新控件的问题
  • 价格周报|供需回归僵局,本周生猪均价与上周基本持平
  • 马上评丨行人转身相撞案:走路该保持“安全距离”吗
  • 溢价26.3%!保利置业42.4亿元竞得上海杨浦宅地,楼板价80199元/平方米
  • 阿里CEO:将以饱和式投入打法,聚焦几大核心战役
  • 新买宝马竟是“维修车”,男子发视频维权被4S店索赔100万
  • 绿城约13.93亿元竞得西安浐灞国际港港务片区地块,区内土地楼面单价首次冲破万元