node-fetch使用FormData上传大文件频繁挂起,求问题排查与解决
问题分析与解决方案
你遇到的大文件上传挂起问题,大概率是node-fetch的fileFrom方法在处理大文件时,流的消费或Content-Length计算出现异常导致的。以下是几个可行的解决方法:
1. 替换fileFrom为原生fs可读流
fileFrom封装的文件对象在大文件场景下可能存在流处理bug,改用Node.js原生的fs.createReadStream更稳定:
import nodeFetch, { FormData } from 'node-fetch'; import { createReadStream } from 'fs/promises'; const fileStream = createReadStream('somefile.txt'); const formData = new FormData(); // 手动指定文件名和MIME类型,模拟fileFrom的效果 formData.append('file', fileStream, { filename: 'somefile.txt', contentType: 'text/plain' }); formData.append('type', 'text/x-gff3'); const auth = { method: 'POST', body: formData, headers: { Authorization: `Bearer ${access.accessToken}`, }, }; const url = new URL(`${access.address}/files`); console.log('START'); try { const response = await nodeFetch(url, auth); console.log(await response.json()); } catch (err) { console.error('上传失败:', err); }
2. 手动添加错误捕获
你的代码缺少错误处理逻辑,挂起可能是因为隐藏的错误导致Promise一直处于pending状态。添加try/catch可以帮你定位具体问题:
// ... 其余代码不变 console.log('START'); try { const response = await nodeFetch(url, auth); // 先检查响应状态,避免非JSON响应导致解析错误 if (!response.ok) { throw new Error(`服务器返回错误: ${response.status} ${response.statusText}`); } console.log(await response.json()); } catch (err) { console.error('上传出错:', err); }
3. 升级node-fetch版本
你使用的v3.3.2版本存在已知的大文件上传相关bug,升级到最新稳定版可能直接解决问题:
npm install node-fetch@latest
4. 手动设置Content-Length(可选)
如果服务器对Content-Length校验严格,node-fetch自动生成的头可能不准确。你可以计算文件大小后手动补充(注意:此方法仅适用于单文件表单,多文件需精确计算整个FormData的总长度):
import { stat } from 'fs/promises'; // ... 其余代码 const fileStats = await stat('somefile.txt'); const auth = { method: 'POST', body: formData, headers: { Authorization: `Bearer ${access.accessToken}`, // 示例:需根据表单实际内容调整总长度 // 'Content-Length': (fileStats.size + 150).toString() }, };
内容的提问来源于stack exchange,提问作者dariober
相关产品推荐
相关产品推荐

