使用Busboy上传docx/rar文件时,file事件未逐个触发的问题排查
文件上传卡住问题排查与修复
问题现象
使用最新版Busboy、Node.js 18及Express.js时:
- 上传10个txt文件可正常完成
- 上传2个docx/rar文件,仅触发一次
file事件且进程卡住;混合docx/rar与txt文件上传时也出现相同问题
核心原因
- 后端未消费文件流:Busboy要求必须消费文件的可读流,否则会因等待流结束信号而卡住进程,无法处理后续文件。txt文件体积小可能触发隐式流结束,但二进制文件(docx/rar)需要显式处理。
- 前端循环变量错误:循环中使用未定义的
file变量,导致无法正确遍历并添加所有文件。
修正代码
前端代码修正
var xmlhttp = new XMLHttpRequest(); xmlhttp.open('POST', uploadUrl, true); xmlhttp.onreadystatechange = function () { // handle status }; var formData = new FormData(); formData.append('size', calculateSize(files)); formData.append('numberOfFiles', files.length); for (let i = 0; i < files.length; i++) { const file = files[i]; // 正确获取当前遍历的文件 console.log(`Append file:${file.name}`); formData.append('files', file); } xmlhttp.send(formData);
后端代码修正
const busboy = new Busboy({ headers: req.headers }); const { inspect } = require('util'); busboy.on('file', function (fieldname, file, filename, encoding, mimetype) { console.log(`In bus boy: ${filename}`); // 消费文件流,避免进程卡住 file.resume(); // 快速跳过流内容,若需要保存文件可替换为写入逻辑 file.on('end', () => { console.log(`File ${filename} processed`); }); }); busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated, encoding, mimetype) { console.log('Field [' + fieldname + ']: value: ' + inspect(val)); }); busboy.on('finish', function() { console.log('All uploads completed'); res.end('Upload success'); // 返回响应结束请求 }); // 将请求流传递给Busboy处理 req.pipe(busboy);
说明
- 后端中
file.resume()会跳过文件内容,若需要保存文件,可替换为fs.createWriteStream配合stream.pipeline实现可靠写入。 - 必须确保调用
req.pipe(busboy),否则Busboy无法获取请求数据。
内容的提问来源于stack exchange,提问作者Crowley
相关产品推荐
相关产品推荐

