React.js使用fetch API上传大文件时触发net::ERR_CONNECTION_ABORTED错误
大文件上传验证失败时前端无法获取后端400响应的解决方案
核心问题分析
你遇到的情况是后端已处理请求并返回400,但前端因TCP连接提前中断,无法正常接收响应,浏览器直接抛出网络错误。Postman正常是因为它对连接中断的处理逻辑和浏览器不同。
具体解决办法
1. 修复后端流处理逻辑
后端使用BufferedInputStream的mark()/reset()验证文件时,若验证失败,必须确保完全读取并丢弃剩余的请求体,否则Tomcat会因未读完请求体而主动中断TCP连接,导致浏览器触发Failed to fetch错误。
示例后端处理逻辑调整:
// 验证失败后,读取剩余流内容 byte[] buffer = new byte[1024]; while (inputStream.read(buffer) != -1) { // 丢弃读取的内容 } inputStream.close(); // 再返回400响应 return ResponseEntity.badRequest().body("无效文件");
2. 调整前端上传方式
直接将File作为请求体发送不是标准的文件上传方式,改用FormData封装更稳定,且不影响后端以流的形式接收文件:
export async function uploadImage(authHeader, id, image) { const url = new URL(`${WEBSTORE_API_URL}/products/${id}/image`); const formData = new FormData(); formData.append('image', image); const requestOptions = { mode: 'cors', method: 'PUT', body: formData, credentials: 'same-origin', headers: { 'Authorization': authHeader // 不要手动设置Content-Type,浏览器会自动生成带boundary的正确值 }, }; try { const response = await fetch(url, requestOptions); // 手动处理非200状态码,避免fetch默认只抛出网络错误 if (!response.ok) { const errorInfo = await response.text(); throw new Error(`上传失败: ${errorInfo}`); } return response; } catch (err) { console.error('上传错误:', err); throw err; } }
3. 配置Spring Boot服务器参数
Tomcat默认的maxSwallowSize为2MB,当请求体超过这个大小且后端拒绝请求时,Tomcat会中断连接。修改配置解除限制:
# 允许服务器 swallow 任意大小的请求体 server.tomcat.max-swallow-size=-1 # 根据需要延长请求超时时间 spring.mvc.async.request-timeout=30000
4. 捕获并处理前端错误
fetch API仅在网络层面失败时抛出错误,HTTP 4xx/5xx状态码不会触发catch块,需要手动判断response.ok并处理,避免遗漏后端返回的错误信息。
内容的提问来源于stack exchange,提问作者Krisztián Lutár
相关产品推荐
相关产品推荐

