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

FastAPI中用Form Data上传1MB+文件时遇Multipart解析错误

解决FastAPI处理Form Data大文件上传时的MultipartParseError问题

问题分析

你遇到的multipart.exceptions.MultipartParseError: Did not find boundary character 154 at index 2错误,本质是手动解析multipart请求时的边界处理逻辑缺陷,加上直接用request.form()处理大文件时,默认的内存解析方式容易触发这类异常。另外代码还存在几个细节问题:

  • pattren拼写错误(应为pattern)
  • 直接访问request.headers['content-type']可能抛出KeyError
  • 手动解析multipart请求不如FastAPI内置的表单处理机制可靠,尤其是大文件场景

解决方案

改用FastAPI官方推荐的File和Form依赖项处理表单上传,这种方式会自动处理multipart边界,大文件会被存储到临时文件而非内存,彻底避免解析异常。

修正后的接口代码

from fastapi import File, Form, UploadFile
import io

@router.post("/document_upload/")
async def upload_files(
    claim_id: str = Form(...),
    claim_type: str = Form(...),
    user: str = Form(...),
    user_age: str = Form(...),
    file: UploadFile = File(...)
):
    # 整理表单数据
    data = {
        "claim_id": claim_id,
        "claim_type": claim_type,
        "user": user,
        "user_age": user_age
    }
    # 读取文件内容到缓冲区
    file_data = await file.read()
    buffer = io.BytesIO(file_data)
    return AWS.upload(data, buffer)

工具函数修正细节

  1. 修正AWS.updoad的拼写错误(应为upload)
  2. 修复S3上传时的字符串格式化嵌套引号语法错误
  3. 调整Metadata中的type字段为实际文件类型,而非固定jpg
  4. 增加文件类型识别失败的异常处理

修正后的AWS.upload代码:

def upload(data, buffer):
    fileinfo = filetype.guess(buffer)
    if not fileinfo:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                            detail="无法识别文件类型")
    ext = fileinfo.extension
    ALLOWED_EXTENSIONS = ["jpg", "jpeg", "pdf", "doc", "docx"]
    buffer.seek(0)
    
    if ext not in ALLOWED_EXTENSIONS:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                            detail="该文件类型不被允许")
                            
    s3_client = boto3.client(
            service_name=settings.SERVICE_NAME,
            aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
            aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY
        )
        
    try:
        filename = f"{data['user']}{data['user_age']}.{ext}"
        s3_path = f"Document/{date.today().strftime('%Y%m%d')}/{data['claim_id']}/{data['claim_type']}/{filename}"
        s3_client.upload_fileobj(
            buffer,
            "bucket-name",
            s3_path,
            ExtraArgs={'Metadata': {'type': ext}}
        )
        buffer.close()
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"上传失败:{str(e)}")

    return {"filename": filename}

额外注意事项

  • Postman发送请求时,确保Body选择form-data,正确添加所有表单字段(claim_id、claim_type、user、user_age)和file字段(选择本地文件上传),Postman会自动生成正确的boundary参数,无需手动设置
  • 如果仍需保留JSON请求的兼容处理,建议拆分两个独立接口实现,避免混合解析逻辑导致的冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 15:45:10