xmlhttp 利用 post 请求发送文件的坑(笔记)

前端

使用 XMLHttpRequest 通过发送 post 请求来发送文件给后端。

let xmlhttp = new XMLHttpRequest();
let fd = new FormData();
fd.append("file", pic_file);
fd.append("token", "tickle");
xmlhttp.open("POST", "http://127.0.0.1/files/");
xmlhttp.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36")
// xmlhttp.setRequestHeader("Content-Type", "multipart/form-data;");
// xmlhttp.setRequestHeader("Sec-Fetch-Site", "same-origin")
xmlhttp.send(fd);

后端

使用 fastapi 作为后端,接受文件。

from fastapi import FastAPI, File, Form, UploadFile

app = FastAPI()

@app.post("/files/")
async def create_file(
    file: UploadFile = File(), token: str = Form()
):
    return {
        "filename": file.filename,
        "content_type": file.content_type,
        "headers": file.headers,
        "file": file.file,
        "status": 1,
        "token": token
    }

遇到的问题

当前端设置了 Content-Type 头部字段时,无论值为什么,都会导致后端无法接收到文件,甚至无法响应请求,返回 400 Bad Request 错误。

其解决方法就是不在前端手动设置 Content-Type 字段,这样才可以正确传输文件,正确响应 post 请求。

其根本原因在于,FormData 需要使用 Content-Type: multipart/form-data; 头部字段,并在后面加上 FormData 的分界线内容,故需要的 Content-Type 的值为 "Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryKhuQzAXRwwLQKgMf"。其中 boundary 为边界信息,内容是 ----WebKitFormBoundary 加一串长度为 16 字符的随机字符串。当请求中未设置该边界信息时,会导致 post 请求响应失败。

当我们不再前端中主动设置这一头部字段,浏览器会在发送 post 请求时自动添加该字段和边界信息,从而才能正确响应 post 请求。

总而言之

xhr 发送 post 请求的时候不要设置 Content-Type 字段。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虚叶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值