React应用仅在火狐下用AbortController取消fetch请求崩溃如何解决?
火狐浏览器下AbortError导致React应用崩溃的解决方案
问题原因
报错详情:Unhandled Rejection (AbortError): The operation was aborted
该问题仅在火狐浏览器出现、Chrome运行正常的核心原因如下:
- fetch请求被AbortController中断时会主动抛出
AbortError类型的Promise拒绝,你的代码没有做异常捕获,火狐对未处理的Promise拒绝的判定规则更严格,会直接触发应用崩溃,Chrome大多场景下仅抛出控制台警告 - 你额外导入了第三方
abort-controllerpolyfill,与火狐原生的AbortController实现存在兼容冲突,主流浏览器早已原生支持该API,无需额外引入polyfill - AbortController实例声明在组件函数顶层,每次组件重渲染都会生成新的实例,存在闭包导致的实例不匹配风险
修正后的代码
import React, { useEffect, useState } from 'react' function Label(){ const [labels, setLabels] = useState([]) useEffect(() => { // 将abortController声明放在useEffect内部,仅挂载时生成一次 const abortController = new AbortController() const signal = abortController.signal async function getLabels(){ try { const req = await fetch(`${process.env.REACT_APP_SERVER_URL}/label`, { credentials: 'include', signal: signal }) const res = await req.json() setLabels(res.data) } catch (err) { // 仅捕获AbortError,其他错误可以按需抛出或处理 if (err.name !== 'AbortError') { throw err } } } getLabels() // 组件卸载时取消HTTP请求 return () => { abortController.abort() } }, []) return (<p>ehehe</p>) }
验证说明
修改后组件卸载时触发的请求中断属于预期行为,抛出的AbortError会被catch捕获,不会产生未处理的Promise拒绝,同时移除了冲突的polyfill、修正了实例声明位置,可同时兼容火狐和Chrome浏览器。
内容的提问来源于stack exchange,提问作者Zulfikar Ahmad
相关产品推荐
相关产品推荐

