aiohttp相关 - 上传文件 + 额外参数

  • 作者:KK

  • 发表日期:2020.02.16


要点速读

主要是通过aiohttp.MultipartWriter('mixed')生成的混合数据写入器将一个个数据片段添加进去的。


目标

本文分享如何构造如下这种文件上传的报文,主要是它除了文件数据外,还有附加的额外参数:

POST http://xxx.com/upload HTTP/1.1
Host: xxx.com
Connection: keep-alive
Content-Length: 55678
Origin: http://xxx.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary3WWhmV5ExQ1g8AYp
Accept: */*
Referer: http://xxx.com/edit.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9

------WebKitFormBoundary3WWhmV5ExQ1g8AYp
Content-Disposition: form-data; name="param1"

param1_value
------WebKitFormBoundary3WWhmV5ExQ1g8AYp
Content-Disposition: form-data; name="param2"

param2_value
------WebKitFormBoundary3WWhmV5ExQ1g8AYp
Content-Disposition: form-data; name="upload_file1"; filename="v2-87951fba754a43b93c879d92d9d03a5f_hd.jpg"
Content-Type: image/jpeg

【下面这里是文件的二进制数据】

代码

import aiohttp, urllib

multipartWriter = aiohttp.MultipartWriter('mixed') #生成一个混合型的多片段数据写入器

#设置前2个参数
multipartWriter.append('param1_value').set_content_disposition('form-data', name = 'param1')
multipartWriter.append('param2_value').set_content_disposition('form-data', name = 'param2')

#设置文件数据
fileHandler = urllib.request.urlopen('http://xxx.jpg') #网络文件
#fileHandler = open('/data/www/project1/111.jpg', 'rb') #本地文件
multipartWriter.append(fileHandler, {'Content-Type': 'image/jpeg'}) \
.set_content_disposition(
	'form-data',
	name = 'upload_file1',
	filename = 'v2-87951fba754a43b93c879d92d9d03a5f_hd.jpg'
)

async with aiohttp.ClientSession() as httpSession:
	async with httpSession.post(
		'http://xxx.com/upload',
		data = multipartWriter, #把数据写入器传到 data 参数这里就好了,
		headers = {'Content-Type': 'multipart/form-data; boundary=' + multipartWriter.boundary} #注意要加上 boundary ,因为这里是声明了数据片段的分隔符,否则服务端不知道以哪个作为分隔符去接收一个个数据片段
	) as response:
		print(await response.text())