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

FastAPI动态表单多文件上传时Starlette FormData仅返回文件名如何解决

问题根源与解决方案

第一步:修复前端表单编码属性

你遇到的str类型报错绝大多数是前端表单未配置正确的编码格式导致的:

  • 表单必须显式添加enctype="multipart/form-data"属性,否则浏览器默认使用application/x-www-form-urlencoded编码,只会把文件名作为普通字符串提交,不会传输文件二进制内容
    示例正确的表单写法:
<form action="/modules/function" method="post" enctype="multipart/form-data">
  <!-- 动态生成的文件输入框,name可以重复或者用自定义前缀识别 -->
  <input type="file" name="upload_file_1">
  <input type="file" name="upload_file_2">
  <button type="submit">提交</button>
</form>

如果是用Fetch/axios等JS动态提交,也要保证构造的FormData对象直接传入请求体,不要手动转成JSON或者其他格式。

第二步:后端动态读取所有上传文件

不需要提前声明参数,直接遍历request.form()拿到的表单数据,筛选所有UploadFile类型的字段即可,适配任意数量的动态上传文件:

from fastapi import FastAPI, Request
from starlette.datastructures import UploadFile

app = FastAPI()

@app.post("/modules/function")
async def function(request: Request):
    form = await request.form()
    upload_files = []
    # 遍历所有表单字段
    for field_name, field_value in form.multi_items():
        # 只筛选类型为UploadFile的字段,自动跳过普通字符串表单字段
        if isinstance(field_value, UploadFile):
            # 读取文件内容,也可以直接保存到磁盘
            filename = field_value.filename
            content = await field_value.read()
            upload_files.append({"filename": filename, "content": content})
            # 读完记得关闭文件对象释放资源
            await field_value.close()
    
    # 后续处理逻辑,返回结果示例
    return {"uploaded_count": len(upload_files), "filenames": [f["filename"] for f in upload_files]}

补充说明

如果表单有多个同名的文件上传字段,用form.getlist("upload_file")可以直接拿到该字段下所有的UploadFile对象列表,不需要全量遍历:

# 多个文件用同一个name属性的场景
files = form.getlist("upload_file")
for file in files:
    if isinstance(file, UploadFile):
        content = await file.read()
        # 处理逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 00:36:03