两台服务器间文件传输异常:接收端无法正确读取文件内容
问题分析与修复方案
核心问题
发送端问题
- 手动创建
FormData后未实际使用,反而直接将单个File对象作为请求体发送,不符合multipart/form-data的传输规范。 - 手动设置
Content-type: multipart/form-data,但缺少必要的boundary分隔符——浏览器/fetch在处理FormData时会自动生成并添加boundary,手动设置会覆盖这个逻辑,导致接收端无法正确解析请求体。
接收端问题
- 直接通过
req.on('data')拼接二进制数据为字符串,这种方式无法正确处理multipart/form-data格式的请求体,且二进制转字符串的过程中容易出现编码错误(你看到的72101108108111是"Hello"每个字符的ASCII十进制码拼接结果,就是编码处理错误导致的)。 - 未使用专门的表单数据解析库,手动解析
multipart/form-data非常容易出错。
修复代码
发送端修复
直接使用FormData作为请求体,不要手动设置Content-Type:
const formData = new FormData(); // 直接用req.file的buffer构建表单数据,无需额外创建File对象 formData.append("file", req.file.buffer, { filename: req.file.originalname, type: req.file.mimetype }); const uploadres = await fetch(url, { method: "POST", headers: { "Authorization": "Bearer " + token // 移除手动设置的Content-Type,fetch会自动添加带boundary的正确头 }, body: formData });
接收端修复
使用multer库解析multipart/form-data请求(这是Node.js处理文件上传的标准方案):
const http = require('http'); const multer = require('multer'); const upload = multer({ storage: multer.memoryStorage() }); // 内存存储,适合测试 const server = http.createServer((req, res) => { // 仅处理上传接口,替换为你的实际路径 if (req.url === '/upload' && req.method === 'POST') { upload.single('file')(req, res, (err) => { if (err) { res.writeHead(500); res.end('上传失败'); return; } // 打印请求信息 console.log(`${req.method} ${req.url} HTTP/${req.httpVersion}`); for (const prop in req.headers) { // 简单实现标题化 const toTitleCase = str => str.replace(/\b\w/g, c => c.toUpperCase()); console.log(`${toTitleCase(prop)}: ${req.headers[prop]}`); } // 读取文件内容并打印 if (req.file) { const content = req.file.buffer.toString('utf8'); console.log('\n' + content); } res.writeHead(200); res.end(); }); } else { res.writeHead(404); res.end('接口不存在'); } }); server.listen(3000, () => { console.log('接收端服务器运行在3000端口'); });
原理说明
- 发送端:
FormData会自动处理文件的封装和boundary生成,确保请求符合multipart/form-data格式,让接收端能正确识别文件部分。 - 接收端:
multer会自动解析请求体中的文件数据,将文件内容封装在req.file.buffer中,直接通过toString('utf8')即可得到正确的文本内容。
内容的提问来源于stack exchange,提问作者Baku
相关产品推荐
相关产品推荐

