一、强缓存与协商缓存的区别
强缓存:浏览器直接读取本地缓存,不发送请求到服务器。通过 Cache-Control
或 Expires
响应头实现。
协商缓存:浏览器发送请求到服务器,由服务器判断资源是否过期。通过 ETag
/If-None-Match
或 Last-Modified
/If-Modified-Since
实现。
二、Vue2 前端实现强缓存(静态资源)
步骤:
- 打包生成哈希文件名:Vue2 默认在
webpack
配置中为文件名添加contenthash
,如app.a1b2c3.js
。 - 服务器配置强缓存头:在 Nginx/CDN 中为静态资源设置
Cache-Control: max-age=31536000
(1年)。
示例 Nginx 配置:
location /static {
alias /path/to/static;
expires 1y; # 等效于 Cache-Control: max-age=31536000
add_header Cache-Control "public";
}
三、Spring Boot 后端实现协商缓存(动态接口)
步骤:
- 添加 ETag 支持:使用
ShallowEtagHeaderFilter
自动生成 ETag。 - 返回带缓存控制的响应:手动设置
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");
}
}
四、测试缓存效果
强缓存:
- 首次请求:返回
200 OK
,响应头包含Cache-Control: max-age=31536000
。 - 再次请求:浏览器直接读取缓存,状态为
200 (from disk cache)
。
- 首次请求:返回
协商缓存:
- 首次请求:返回
200 OK
,响应头包含ETag: "a1b2c3"
。 - 再次请求:请求头携带
If-None-Match: "a1b2c3"
,若未修改,服务器返回304 Not Modified
。
- 首次请求:返回
五、注意事项
- 前端静态资源:确保文件名哈希变化,避免旧缓存影响新版本。
- 动态接口:敏感数据避免使用强缓存,优先用
no-cache
或private
。 - 测试工具:使用浏览器开发者工具的 Network 面板检查响应头与缓存状态。
总结:强缓存通过设置长时间 max-age
实现,适用于静态资源;协商缓存通过 ETag/Last-Modified 验证,适用于动态数据。Vue2 利用打包哈希 + 服务器配置,Spring Boot 通过响应头控制实现。