Node.js用fetch向Golang API传文件失败(Postman可正常调用)
Node.js node-fetch 发送文件请求到Golang API返回400的排查与解决
问题核心
你的代码和Postman的关键差异在于文件字段的构造方式:Postman在formdata.append时指定了文件名参数,而你的代码仅传递了文件内容(Buffer),导致Golang API无法正确解析multipart表单中的文件字段,返回400错误。
Golang的multipart.Form解析时,通常需要每个文件字段包含filename信息,否则会判定表单格式不合法。
解决方案
1. 给FormData.append添加文件名参数
修改文件字段的append逻辑,补充文件名参数(对应Postman的第三个参数),确保multipart字段携带正确的文件名信息:
let formData = new FormData() formData.append('postUUID', postUuid) // 用forEach遍历更合理(无需返回数组) json.data.uploadIds.forEach((upl) => { let file = data.files.find(el => el === upl.filename) if (!file) { console.error(`找不到文件: ${upl.filename}`) return } // 方式1:推荐用流式读取(适合大文件,减少内存占用) formData.append(upl.uuid, fs.createReadStream(file), upl.filename) // 方式2:如果用Buffer读取,同样需要添加文件名参数 // formData.append(upl.uuid, fs.readFileSync(file), upl.filename) }) // 注意:不要手动设置Content-Type为multipart/form-data // FormData会自动生成带boundary的Content-Type头,手动设置会丢失boundary导致解析失败 let headers = new Headers() headers.append('Authorization', 'Bearer '+token) headers.append("Accept", "application/json"); fetch(`${API}/posts/uploadMediaFiles`, { method: 'POST', headers, body: formData })
2. 额外注意事项
- Node环境的FormData依赖:如果是Node.js环境(非浏览器),确保你使用的是
form-data包(需npm安装),或者node-fetch v3+内置的FormData实现,两者都支持文件名参数。 - 字段名一致性:确认
upl.uuid和Golang API期望的文件字段名完全匹配(和Postman中的字段名一致)。 - MIME类型(可选):如果API要求指定文件MIME类型,可以通过配置对象传递:
formData.append(upl.uuid, fs.createReadStream(file), { filename: upl.filename, contentType: 'image/jpeg' // 根据文件类型调整 })
内容的提问来源于stack exchange,提问作者Алексей Колесников
相关产品推荐
相关产品推荐

