keepalive 是 fetch api 的布尔选项,用于页面卸载时尽力发送请求,仅支持 get/post、限制请求体大小、禁用 cors 预检且无法获取响应;推荐优先使用更可靠的 navigator.sendbeacon()。

keepalive 是 Fetch API 中一个布尔选项,用于指示浏览器在页面卸载(如关闭标签页、刷新、导航离开)时仍尝试异步发送请求。它不保证请求一定成功送达服务器,但能显著提升“临终请求”(如埋点、日志上报、状态保存)的发送成功率。
keepalive 的核心作用和限制
当设置 keepalive: true 时,Fetch 请求会被标记为“高优先级卸载任务”,浏览器会延长当前页面的生命周期一小段时间(通常几百毫秒),以尽力完成该请求。但它有明确限制:
- 只支持 POST 或 GET 方法(其他方法如 PUT/DELETE 不被允许)
- 请求体大小受限(Chrome 当前上限约 64KB,具体取决于浏览器实现)
- 不能使用需要 CORS 预检的请求(即不能带自定义 header、不能用非简单 content-type)
- 响应结果无法被 JavaScript 获取(因为页面已不可用),所以
then()或catch()无意义
正确使用 keepalive 发送请求的写法
只需在 fetch() 的 options 参数中添加 keepalive: true,并确保满足上述限制条件。典型场景是用户离开前上报行为:
window.addEventListener('beforeunload', () => {
fetch('/api/log', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ event: 'page_exit', timestamp: Date.now() }),
keepalive: true
});
});
注意:不要 await 或链式处理该 fetch,否则可能阻塞卸载流程或报错;也无需检查响应,因为页面即将销毁。
替代方案与兼容性提醒
keepalive 在现代浏览器中支持良好(Chrome 49+、Firefox 47+、Edge 79+、Safari 11.1+),但旧版 Safari(≤11.0)不支持。若需降级兼容,可结合 navigator.sendBeacon():
-
sendBeacon()专为此类场景设计,更可靠,且支持更大 payload(64KB+) - 它只支持 POST,且数据必须是
ArrayBuffer、Blob、FormData或字符串 - 示例:
navigator.sendBeacon('/api/log', JSON.stringify(data))
实际项目中,建议优先用 sendBeacon();若需 fetch 语义(如复用现有逻辑),再用 keepalive: true,并做好降级判断。
常见误区与调试建议
很多人误以为 keepalive 能“强制发完请求”,但实际它只是尽力而为。调试时注意:
- Network 面板中可能看不到 keepalive 请求(因页面已卸载),可用服务端日志验证是否收到
- 本地开发时,禁用缓存并开启“Preserve log”,有助于观察卸载阶段的请求
- 避免在 keepalive 请求中依赖 cookie 或认证头(尤其是 SameSite 严格模式下可能被拦截)
- 不要在
unload事件中使用 keepalive —— 应用beforeunload或直接监听visibilitychange(当document.visibilityState === 'hidden')
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











