React组件单个fetch请求触发服务器多次GET请求问题求助
问题原因分析
- 首先你的代码存在笔误:
return res.json()写在console.log("Getting json from response")之前,这行日志永远不会执行,你观测到的日志次数不能作为逻辑执行次数的判断依据。 - 核心问题(
Fetching data日志仅1次,但网络请求超过10次)的常见原因如下:- 接口存在循环重定向:后端接口返回3xx重定向状态码,且跳转目标指向自身或形成循环跳转链,fetch默认会自动跟随重定向,每跳转一次就会产生一条新的网络请求,但fetch调用本身只触发1次,所以日志仅打印1次,直到浏览器达到重定向次数上限才会停止。
- 跨域预检请求未缓存:如果请求是跨域非简单请求,浏览器每次发起GET前会先发送OPTIONS预检请求,若后端未配置
Access-Control-Max-Age响应头缓存预检结果,会导致每次请求都伴随一条OPTIONS请求,若同时存在重定向,请求总数会翻倍。 - 开发环境代理工具异常:Webpack DevServer、Vite等开发服务的代理配置错误,会导致单条请求被多次转发到后端,也会出现请求次数多但前端逻辑仅执行1次的情况。
- 组件子级触发额外请求:你传入数据的
TutorialList组件内部如果有遍历每条数据发起请求的逻辑,也会产生大量请求,且这些请求不会触发Home组件的useEffect日志。
排查步骤
- 打开浏览器网络面板,确认所有请求的类型、状态码:
- 如果存在大量3xx状态的请求,查看响应头
Location字段,确认是否存在循环重定向。 - 如果存在大量OPTIONS请求,确认跨域配置是否符合预期。
- 如果存在大量3xx状态的请求,查看响应头
- 注释掉
TutorialList组件的引用,仅渲染原始接口返回数据,观察请求次数是否恢复正常,排除子组件的问题。 - 打包生产环境代码直接运行,若问题消失则为开发环境工具链导致,无需处理线上逻辑。
修复方案
- 修正代码笔误,调整then链顺序:
useEffect(() => { console.log("Fetching data"); fetch("http://192.168.212.52:8080/api/tutorials/all/") .then((res) => { console.log("Getting json from response"); return res.json(); }) .then((data) => { console.log(data); setTutorials(data); }); }, []);
- 如果是循环重定向问题:修正后端重定向规则,或直接请求最终目标地址(比如把http改为https,避免后端强制跳转)。
- 如果是OPTIONS请求过多:后端配置
Access-Control-Max-Age响应头,设置合理的预检缓存时长(比如86400,即缓存24小时)。 - 增加请求取消逻辑,避免组件卸载后无效请求继续执行:
useEffect(() => { const controller = new AbortController(); console.log("Fetching data"); fetch("http://192.168.212.52:8080/api/tutorials/all/", { signal: controller.signal }) .then((res) => { console.log("Getting json from response"); return res.json(); }) .then((data) => { setTutorials(data); }) .catch(err => { if(err.name !== 'AbortError') console.error('请求错误:', err); }); // 组件卸载时取消请求 return () => controller.abort(); }, []);
内容的提问来源于stack exchange,提问作者Tallented-Code-bot
相关产品推荐
相关产品推荐

