You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

multipart/form-data POST请求body构造及JS调用API报400错误排查

解决multipart/form-data POST请求的400错误及相关问题

一、核心参数格式说明

“文件字节”指的是文件本身的二进制数据,不需要手动转成字节数组——FormData会自动处理文件的二进制编码。你在Postman中调整键名后请求正常,说明接口对参数键名有严格要求,JS代码报错大概率是参数构造不符合接口规范。

二、HTML+JavaScript 正确请求示例

以下是符合标准的请求代码,注意键名必须和你Postman中调通的完全一致:

// 获取页面上的文件选择控件
const fileInput = document.getElementById('file-upload');
const selectedFile = fileInput.files[0];

if (!selectedFile) {
  console.error('请选择文件');
  return;
}

// 构造FormData对象
const formData = new FormData();
// 这里的键名(比如'file')要和Postman中使用的完全匹配
formData.append('file', selectedFile);

// 可选的文档元数据,假设接口要求键名为'document',值为JSON字符串
const docMetadata = {
  title: '用户上传文档',
  category: '技术文档',
  uploadTime: new Date().toISOString()
};
// 直接将JSON转为字符串追加到FormData
formData.append('document', JSON.stringify(docMetadata));

// 发送POST请求
fetch('你的接口地址', {
  method: 'POST',
  body: formData
  // 不要手动设置Content-Type,fetch会自动生成带boundary的正确头
})
.then(res => {
  if (!res.ok) throw new Error(`HTTP错误:${res.status}`);
  return res.json();
})
.then(result => console.log('请求成功:', result))
.catch(err => console.error('请求失败:', err));

如果接口要求元数据以application/json类型的part传递,可将JSON转为Blob后追加:

formData.append('document', new Blob([JSON.stringify(docMetadata)], { type: 'application/json' }));

三、对应的curl命令写法

根据你Postman的正确请求,可转化为以下curl命令(替换占位符为实际值):

基础版本(元数据为JSON字符串)

curl -X POST "你的接口地址" \
  -F "file=@/本地文件的绝对路径/示例.pdf" \
  -F "document={\"title\":\"用户上传文档\",\"category\":\"技术文档\"}"

指定元数据Content-Type版本

如果接口要求元数据part的Content-Type为application/json:

curl -X POST "你的接口地址" \
  -F "file=@/本地文件的绝对路径/示例.pdf" \
  -F "document={\"title\":\"用户上传文档\",\"category\":\"技术文档\"};type=application/json"

四、文档元数据的获取与解析

前端获取文件自带元数据

如果需要获取上传文件的原生元数据(如文件名、大小、类型),直接从File对象读取:

console.log('文件名:', selectedFile.name);
console.log('文件大小:', selectedFile.size + '字节');
console.log('文件类型:', selectedFile.type);

后端解析请求中的元数据

以两种常见后端技术栈为例:

Node.js(Express + multer)

const express = require('express');
const multer = require('multer');
const app = express();
// 不保存文件到本地,仅解析请求
const upload = multer({ storage: multer.memoryStorage() });

app.post('/upload', upload.fields([{ name: 'file' }, { name: 'document' }]), (req, res) => {
  // 获取文件信息
  const uploadedFile = req.files.file[0];
  // 解析元数据JSON
  const docMetadata = req.body.document ? JSON.parse(req.body.document) : null;
  res.json({
    status: 'success',
    fileInfo: { name: uploadedFile.originalname, size: uploadedFile.size },
    metadata: docMetadata
  });
});

app.listen(3000);

Python(Flask)

from flask import Flask, request
import json

app = Flask(__name__)

@app.route('/upload', methods=['POST'])
def upload_file():
    # 获取上传的文件
    file = request.files.get('file')
    # 获取元数据字符串并解析
    metadata_str = request.form.get('document')
    doc_metadata = json.loads(metadata_str) if metadata_str else None
    
    return {
        'status': 'success',
        'file_name': file.filename if file else None,
        'metadata': doc_metadata
    }

if __name__ == '__main__':
    app.run(debug=True)

内容的提问来源于stack exchange,提问作者John117

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 00:01:15