页面刷新时避免Fetch请求触发NetworkError的解决方案
解决页面刷新时轮询Fetch请求触发NetworkError的问题
方法1:使用AbortController中止未完成的请求
利用浏览器AbortController API,在页面即将卸载时主动中止正在进行的Fetch请求,从根源避免这类错误抛出。修改后的代码如下:
let abortController = null; function pollingLoop() { setTimeout(() => { abortController = new AbortController(); const signal = abortController.signal; fetch("http://some.url", { signal }) .then(response => doStuffWithResponse(response)) .catch(ex => { // 仅处理非主动中止的错误 if (ex.name !== 'AbortError') { console.error(ex); } }) .finally(() => { abortController = null; pollingLoop(); }); }, 2000); } // 页面刷新/关闭时中止请求 window.addEventListener('beforeunload', () => { if (abortController) { abortController.abort(); } });
- 每次发起请求前创建新的
AbortController,并将其signal传入Fetch配置 - 监听
beforeunload事件,在页面卸载时调用abort()终止未完成的请求 - catch块中过滤掉
AbortError,只记录真正的业务或网络异常
方法2:在Catch中识别并忽略页面卸载导致的错误
如果不想引入AbortController,也可以直接在catch逻辑中判断错误类型,忽略页面卸载触发的预期错误:
function pollingLoop() { setTimeout(() => { fetch("http://some.url") .then(response => doStuffWithResponse(response)) .catch(ex => { // 忽略页面卸载或网络中断导致的预期错误 if (ex.name === 'NetworkError' && !navigator.onLine) { return; } // 部分浏览器会返回特定错误信息,可针对性判断 if (ex.message.includes('The user aborted a request')) { return; } console.error(ex); }) .finally(() => pollingLoop()); }, 2000); }
这种方法实现简单,但错误判断条件可能因浏览器略有差异,可靠性不如AbortController方案。
额外优化建议
- 保持当前轮询逻辑:请求完成后再等待2秒发起下一次请求,避免请求叠加
- 可增加失败退避策略:比如请求失败后延长轮询间隔,减少无效请求频次
内容的提问来源于stack exchange,提问作者Selbi
相关产品推荐
相关产品推荐

