从浏览器向FastAPI的UploadFile流式传输请求报错求助
问题解决:FastAPI UploadFile接口报"Expected UploadFile, received: <class 'str'>"
错误原因
- 直接将
ReadableStream对象添加到FormData中,浏览器无法将其识别为文件流,反而会把流对象转换为字符串(如[object ReadableStream]),导致FastAPI接收到的是字符串而非文件。 - 手动设置
Content-Type: Multipart/form-data会覆盖axios自动生成的带边界分隔符(boundary)的请求头,而multipart/form-data必须依赖boundary才能正确解析字段,这也会导致FastAPI无法识别文件。
解决方法
方法一:直接使用File对象(推荐,无需手动处理流)
File对象本身已经支持流式处理,直接添加到FormData即可:
let formData = new FormData(); // 直接添加File对象,无需包装成ReadableStream formData.append("files", this.files[0]); axios({ url: this.$appConfig.file_url, method: 'put', data: formData, params: {'filename': filename}, headers: { "Authorization": `Bearer ${this.$store.getters.token}` }, // 不要手动设置Content-Type,axios会自动生成带boundary的正确头 })
方法二:自定义流式上传(适用于大文件分块等场景)
如果确实需要自定义流处理,需要将流包装成Blob对象(FormData支持Blob),并确保传递文件名:
let formData = new FormData(); const that = this; const file = that.files[0]; // 创建读取文件内容的流 const stream = new ReadableStream({ async start(controller) { const reader = file.stream().getReader(); while (true) { const { done, value } = await reader.read(); if (done) break; controller.enqueue(value); } controller.close(); } }); // 将流包装为Blob,指定文件MIME类型 const blob = new Blob([stream], { type: file.type }); // 第三个参数指定文件名,FastAPI会通过这个获取文件名 formData.append("files", blob, file.name); axios({ url: this.$appConfig.file_url, method: 'put', data: formData, params: {'filename': filename}, headers: { "Authorization": `Bearer ${this.$store.getters.token}` }, })
补充说明
- FastAPI端的路由代码无需修改,只要请求正确传递文件,
List[UploadFile]就能正常接收。如果要上传多个文件,多次调用formData.append("files", file)即可。
内容的提问来源于stack exchange,提问作者manbearpig
相关产品推荐
相关产品推荐

