JavaScript中防Ajax缓存需在请求URL末尾添加毫秒级时间戳,推荐通过重写window.fetch、axios拦截器或patch XMLHttpRequest.open统一处理,仅对GET/HEAD请求且无t参数时注入。

在 JavaScript 中,Ajax 请求默认可能被浏览器缓存(尤其是 GET 请求),导致获取到过期数据。为防止缓存污染,常见做法是在 URL 后追加时间戳(如 ?t=1715823456789)。若项目中大量使用原生 fetch 或 XMLHttpRequest,手动加时间戳易遗漏;推荐在全局拦截层统一处理。
使用 fetch 全局拦截(推荐)
现代项目多用 fetch,可通过重写全局 window.fetch 实现统一注入时间戳:
- 只对 GET、HEAD 等幂等请求添加时间戳,避免影响 POST/PUT 等带 body 的请求
- 不修改已有查询参数,仅在无重复
t参数时追加 - 确保时间戳是毫秒级,且每次请求独立生成(不能复用)
示例代码:
// 保存原始 fetch
const originalFetch = window.fetch;
window.fetch = function(url, options = {}) {
// 只处理 GET/HEAD 请求
const method = (options.method || 'GET').toUpperCase();
if (!['GET', 'HEAD'].includes(method)) {
return originalFetch(url, options);
}
// 解析 URL,安全添加 t 参数
const urlObj = new URL(url, window.location.origin);
if (!urlObj.searchParams.has('t')) {
urlObj.searchParams.set('t', Date.now().toString());
}
return originalFetch(urlObj.toString(), options);
};
适配 axios 的请求拦截器
若项目使用 axios,更简洁的方式是配置请求拦截器:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 利用
config.url和config.params统一注入 - 避免覆盖用户已传的
params.t,可设为“仅当未提供时补充” - 注意:GET 请求的参数优先级为
params> URL 查询字符串
示例:
axios.interceptors.request.use(config => {
if (['get', 'head'].includes(config.method?.toLowerCase())) {
config.params = {
...config.params,
t: config.params?.t ?? Date.now()
};
}
return config;
});
兼容 XMLHttpRequest 的全局 patch
针对老项目仍大量使用 XMLHttpRequest 的场景,可劫持 open 方法:
- 监听
GET请求,在调用open前改写 URL - 需判断是否已含
t=,避免重复添加 - 注意:不要影响非 GET 请求,也不应修改 POST 的 URL(body 才是数据主体)
示例:
const originalOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
if (/^(get|head)$/i.test(method)) {
const urlObj = new URL(url, document.baseURI);
if (!urlObj.searchParams.has('t')) {
urlObj.searchParams.set('t', Date.now());
}
url = urlObj.toString();
}
return originalOpen.call(this, method, url, async, user, password);
};
注意事项与替代方案
时间戳防缓存只是手段之一,实际开发中还需注意:
-
服务端配合:响应头设置
Cache-Control: no-cache或max-age=0更规范 -
避免过度依赖:某些 CDN 或代理可能忽略查询参数,此时需用
Cache-Control: no-store -
调试友好性:时间戳会让 URL 变长,DevTools 中不易比对;可考虑开发环境用固定值(如
t=dev) - 不适用于 JSONP:JSONP 是 script 标签加载,需单独处理,且现代项目已基本弃用
不复杂但容易忽略。关键是在请求发出前、URL 最终确定那一刻插入唯一、新鲜的时间标识。

















