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

强缓存和协商缓存

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

强缓存 :浏览器直接读取本地缓存,不发送请求到服务器。通过 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 配置

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

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

步骤

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

示例代码

java 复制代码
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 通过响应头控制实现。

相关推荐
梅孔立4 小时前
两种免费的翻译API调用方式详解 - Edge官方API与个人缓存服务
前端·缓存·edge
gwf2164 小时前
SSD读写速度深度解析:顺序读写vs随机读写、IOPS、延迟,你的硬盘性能到底怎么看?
git·嵌入式硬件·缓存·github·智能硬件
番茄炒鸡蛋加糖6 小时前
缓存三大问题
缓存
江晓鱼未暖11 小时前
十七、Redis 核心原理与架构详解
大数据·数据库·数据仓库·redis·缓存·架构
小罗水11 小时前
第13章 Redis 缓存、幂等锁与任务状态
数据库·redis·缓存
热心市民lcj12 小时前
Spring Boot 整合 Caffeine 本地缓存实战
spring boot·后端·缓存
zx11545013 小时前
【热点 Key 探测与加长缓存 TTL 实战】
缓存
toooooop81 天前
如何用 ss + ps 精准定位本机 Redis 的“隐形”消费者?
linux·数据库·redis·缓存
软萌萌的11 天前
C#中的多级缓存架构设计与实现深度解析
缓存·c#·wpf
醉城夜风~1 天前
HTML表单域学习博客:表单标签、输入框、按钮详解
android·java·缓存