做前端开发的人,几乎天天和 AJAX 打交道。发个请求,拿点数据,刷新一下页面局部,用户体验看起来挺流畅。但有个问题经常被忽略:AJAX 请求到底要不要加缓存?
浏览器其实默认就缓存了某些 AJAX 请求
很多人以为 AJAX 是“新鲜数据”,所以一定不会走缓存。其实不然。只要请求方式是 GET,URL 一样,浏览器很可能直接从内存或磁盘里拿之前的响应,根本不会发出去。
比如你在管理后台点“刷新用户列表”,连续点了两次,如果 URL 是 /api/users,而且是 GET 请求,第二次可能压根没走网络,直接用了上一次的结果。用户没变,你却以为系统卡了。
该缓存的时候要让它缓存
有些场景下,缓存反而是好事。比如加载一个静态配置项,像省市区的下拉数据,一天变不了几次。每次打开页面都去请求一遍,既拖慢速度,又增加服务器压力。
这时候可以合理利用浏览器缓存机制。设置合适的 Cache-Control 响应头,比如:
Cache-Control: public, max-age=3600
这样同一个页面在 1 小时内再次发起相同的 GET 请求,就会直接用缓存,提升加载速度。
不该缓存的时候要想办法绕过
但更多时候,我们想要的是“最新数据”。比如订单状态、消息未读数、实时股价。这种数据一旦缓存,用户看到的就是错的。
常见的解决办法是在 URL 后面加个时间戳或者随机参数:
$.ajax({
url: "/api/order/status?t=" + Date.now(),
type: "GET",
success: function(data) {
// 更新界面
}
});
或者用 cache: false(jQuery 支持):
$.ajax({
url: "/api/order/status",
type: "GET",
cache: false,
success: function(data) {
// 自动加 _t= 时间戳
}
});
Fetch 和原生 XMLHttpRequest 默认不会主动加这些,得自己处理。
POST 请求一般不缓存,但也不绝对
按规范,POST 请求不会被浏览器缓存,所以常用来“强制刷新”数据。但这不代表它绝对安全。如果服务端返回了明确的缓存头,某些代理或中间件仍可能缓存响应。
真正关键的接口,除了用 POST,还得配合服务端设置:
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
这样才能确保数据不会被任何环节留底。
移动端 WebView 更容易踩坑
很多 App 内嵌网页用的是 WebView,这类环境对缓存更“积极”。你测试时好好的,上线后用户反馈数据不对,一查发现是 WebView 把 AJAX 结果缓了两天。
所以涉及用户登录态、权限变更、支付结果这类敏感操作,必须手动控制缓存行为,不能依赖默认机制。
别让缓存成了安全隐患
缓存不只是性能问题,还可能泄露信息。比如某个 AJAX 接口返回了用户的身份证号,即使用户已退出,缓存在本地,下次打开页面可能又被还原出来。
特别是公共设备上,这种风险更高。涉及敏感数据的接口,不仅要禁用缓存,还要考虑传输加密和生命周期管理。
说到底,AJAX 加不加缓存,不是“要”或“不要”的选择题,而是根据数据类型、使用场景和服务要求做的权衡。该快的时候快,该稳的时候稳,才能既保证体验又守住底线。