React+Fastify应用浏览器请求随机挂起问题排查求助
问题:React+Webpack+Fastify应用API请求偶尔无限挂起
问题概述
基于ReactJS、Webpack和Fastify开发的Web应用,前端向后端API发起请求时偶尔出现**请求无限挂起(pending状态)**的异常。Fastify同时负责提供Webpack编译后的静态文件和API路由,问题与具体调用的路由无关。
关键现象
- 浏览器端:Chrome和Firefox均出现该问题;相同URL的重复请求会被浏览器阻塞;切换不同URL请求后,之前阻塞的请求会完成,但最早挂起的请求仍处于pending状态
- 服务器端:已完整接收并处理请求,Fastify日志显示
reply.sent为true,但响应从未到达浏览器 - 网络层面:Wireshark未捕获到异常请求的响应包;无交互时每3秒存在约70字节的TCP ACK通信;正常与异常请求仅TCP基础字段(帧编号、序列号、窗口大小等)存在差异
前端代码片段
请求工具函数
export const fetcher = async (url, method = 'GET', body = null) => { const res = await fetch(url, { method, headers: { 'Content-Type': 'application/json', // 用户认证后浏览器会自动添加Cookies }, body: body ? JSON.stringify(body) : null, }); if (!res.ok) { let err = await res.json(); if (err.message) throw err; else return err; } return res.json(); };
调用示例
<button onClick={async () => { let document = await fetcher(`/api/information/${docId}`); alert(`${document.title} is the title of my document !`); }} />
复现步骤
- 点击docId=1的按钮,请求成功并弹出文档标题
- 几秒后再次点击同docId按钮,请求挂起,Promise从未resolve
- 再次点击该按钮,Chrome因存在相同pending请求而阻塞此请求
- 点击docId=2的按钮,请求成功并弹出标题
- 步骤3的请求解除阻塞并完成,但步骤2的请求仍处于pending状态
可能的问题根源排查方向
1. Fastify连接与响应处理异常
- 检查Fastify的
keepAlive配置:本地开发时可尝试关闭keepAlive(设置keepAlive: false),测试TCP连接复用是否导致异常 - 排查响应发送逻辑:确认路由/中间件中是否存在未完整调用
reply.send()的情况,或异步操作未正确await导致响应发送延迟 - 开启详细日志:将Fastify日志级别设为
trace,观察响应发送的完整流程是否存在异常
2. Webpack与Fastify的协同冲突
- 若使用Webpack Dev Server代理静态文件,尝试改为直接由Fastify serve静态资源,排查端口代理或连接池冲突
- 关闭Webpack热重载功能,测试是否因热重载导致浏览器与服务器连接状态异常
3. 浏览器缓存与连接机制限制
- 绕过浏览器请求合并:在请求URL后添加随机参数(如
?t=${Date.now()}),避免相同URL的请求被浏览器合并处理 - 检查浏览器连接状态:通过Chrome的
chrome://net-internals/#sockets查看是否存在异常的ESTABLISHED连接,排查TCP连接复用问题
4. 本地网络环境干扰
- 关闭防火墙、杀毒软件等工具,测试是否存在TCP包被拦截的情况
- 切换本地网络环境(如WiFi/有线),排查是否与特定网络的NAT或端口转发配置有关
5. Fetch API的潜在问题
- 替换请求库:改用axios发起请求,排除Fetch API的实现差异导致的异常
- 显式设置
credentials:在Fetch配置中添加credentials: 'same-origin'(或'include'),确认Cookie传递是否影响连接状态
内容的提问来源于stack exchange,提问作者Jean-Samuel Girard
相关产品推荐
相关产品推荐

