使用Formidable获取FormData文件后转发出现文件损坏问题排查
问题分析与修复方案
核心问题点
错误直接传入Formidable文件对象到FormData
Formidable解析返回的file是包含元数据和临时路径的对象,并非实际文件内容或可读流,直接append会导致发送的是对象的字符串化内容,而非真实文件数据,这是文件损坏、字节数偏小的根本原因。手动设置的请求头与FormData逻辑冲突
- 手动指定
Content-Type: application/octet-stream,但使用FormData作为请求体时,运行时会自动生成multipart/form-data类型的请求头(包含正确的boundary分隔符),手动覆盖会导致接收端无法正确解析文件结构。 - 手动添加
Content-Disposition头完全多余,FormData在append文件时会自动处理该字段的格式与内容。
修复后的代码
// Retrieve data. const form = formidable({ multiples: true }); const fs = require('fs'); // 确保引入fs模块 form.parse(request, async (err: any, fields: any, files: any) => { if (!drupal) { return response.status(500).send('Empty drupal handler.'); } const { fieldName, webformId } = fields; const file = files[fieldName]; if (fieldName && webformId && file) { // Build api url. const url = drupal.buildUrl( `/webform_rest/${webformId}/upload/${fieldName}` ); // Build file form data: 传入文件可读流与元数据 const body = new FormData(); // Formidable v3+ 使用filepath字段,v2及以下用path body.append('file', fs.createReadStream(file.filepath), { filename: file.originalFilename, contentType: file.mimetype }); // Send file data. const result = await drupal.fetch(url.toString(), { method: 'POST', // 移除手动设置的Content-Type和Content-Disposition,交由FormData自动处理 body, withAuth: true, }); const resultData = await result.json(); if (result.ok && 'fid' in resultData) { return response.status(200).json(resultData.fid[0]['value']); } return response.status(500).send({ error: result.statusText }); } });
额外注意事项
- 确认项目已安装并引入
fs模块(CommonJS用require,ES模块用import)。 - 根据Formidable版本调整文件路径字段:v3+用
file.filepath,v2及以下用file.path。 - 可在发送前校验临时文件的可读性,避免因文件读取失败引发的异常。
内容的提问来源于stack exchange,提问作者Hasina Njaratin
相关产品推荐
相关产品推荐

