0%

Python笔记:requests通过multipart/form-data上传文件

今天测试一个上传文件的接口,然后,习惯了 RESTful API 的我看到接口请求的内容时懵了,它是这样色儿的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
------WebKitFormBoundarydAn5AoMCXEY0gLCj
Content-Disposition: form-data; name="file"; filename="test.pdf"
Content-Type: application/pdf


------WebKitFormBoundarydAn5AoMCXEY0gLCj
Content-Disposition: form-data; name="env"

dev
------WebKitFormBoundarydAn5AoMCXEY0gLCj
Content-Disposition: form-data; name="filePath"

a5542170-a654-11eb-a044-a5bf1ae497a1/test.pdf
------WebKitFormBoundarydAn5AoMCXEY0gLCj--

这……不会玩了!

一通无语后,看了眼 headers 里的 Content-Type

1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarydAn5AoMCXEY0gLCj

呵呵,multipart/form-data 是什么类型?后面那个 boundary 又是什么?

一通“百度”,终有所获。

什么是 multipart/form-data

multipart/form-data 是 RFC1867 协议中包含的变更,包括 HTTP headersbody 变更。

从上文可以看到,headers 变化很明显了,就是 Content-Type 变成了如下格式:

1
Content-Type: multipart/form-data; boundary=${bound}

即表单类型呢就是 multipart/form-data,字面上看就是“分为多个部分的表单数据”。以什么分割呢,就是后面的 boundary,意即分隔线——它是随机生成的一个字符串,在 body 中用以 --${bound} 分割各数据字段。

基本原理搞明白了,那就要撸代码发请求了。

使用 Python 发请求

这里笔者使用 Python 的 requests 库来完成请求。话不多说,上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
import requests

def test_upload_file(self):
upload_api_url = self.host + self.upload_api_path
file = {
'file': open(self.attachment_file, 'rb')
}
data = {
'env': 'dev',
'filePath': self.filepath
}
response = requests.post(upload_api_url, files=file, data=data)
print(response.text)

Python 代码很简单,只需要指定接口 URL,并传入要上传的文件,以及要提交的其他数据字段,发送一个 post 请求就 OK 啦!

只需要注意几点:

  1. 上传的文件与其他数据字段是分别指定参数传入的;
  2. 文件最好以二进制流的方式提供。