加时间戳防止缓存的原理:
1. 缓存机制的工作原理
浏览器和代理服务器会根据完整的URL作为缓存的键(key)。当URL完全相同时,它们可能不会发起新请求,而是直接返回缓存的结果。
2. 时间戳如何打破缓存
// 第一次请求
URL: /v1/orders?timestamp=1638321234567
// 第二次请求(即使其他参数相同)
URL: /v1/orders?timestamp=1638321239999 // 时间戳不同!
// 缓存系统看到两个不同的URL,会认为这是两个不同的请求
3. 实际应用场景
// 有缓存的可能问题
fetch('/api/data') // 多次请求相同URL可能返回缓存
// 加时间戳防止缓存
fetch(`/api/data?t=${Date.now()}`) // 每次都不同,强制重新请求
4. 为什么POST请求也需要防缓存
虽然POST请求理论上不应该被缓存,但:
- 某些浏览器或代理可能有异常实现
- 一些中间件(如CDN、API网关)可能配置不当
- 防止历史请求被误用
- 确保调试时能获取最新数据
5. 其他防缓存的方法
const orderConfig = {
params: {
// 方法1:时间戳(最常用)
_t: Date.now(),
// 方法2:随机数
_r: Math.random(),
// 方法3:版本号(用于强制更新)
_v: '1.0.0',
// 方法4:使用请求ID
requestId: uuidv4()
},
headers: {
// 方法5:设置请求头禁止缓存
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0'
}
}
6. 注意事项
// 1. 注意参数命名,避免与业务参数冲突
params: {
timestamp: Date.now(), // 通常加下划线或特殊前缀
_: Date.now(), // 更简洁的写法
nocache: Date.now() // 语义明确的写法
}
// 2. 对于GET请求尤其重要
const getMenuConfig = {
method: 'get',
params: {
restaurantId: 'res_456',
_: Date.now() // GET请求必须加时间戳!
}
}
// 3. 在axios中可以全局配置
axios.interceptors.request.use(config => {
if (config.method === 'get') {
config.params = {
...config.params,
_t: Date.now()
}
}
return config;
});
总结: 时间戳通过让每次请求的URL都不同,强制缓存系统将其视为新请求,从而绕过缓存机制,确保获取最新数据。这在需要实时数据的场景(如外卖、支付、聊天)中非常重要。