最近需要写一个批量上传固件的脚本,中间涉及到请求中利用multipart/form-data表单来提交文件数据

所以这个脚本的实现最关键的地方是请求的模拟

通过fidder抓包发现提交的数据为如下:

------WebKitFormBoundarym3TVRM3XmuMfHSO2
Content-Disposition: form-data; name="projectId"

-1
------WebKitFormBoundarym3TVRM3XmuMfHSO2
Content-Disposition: form-data; name="siteId"

-1
------WebKitFormBoundarym3TVRM3XmuMfHSO2
Content-Disposition: form-data; name="name"

C2_2.1.0.1546_2018-05-25
------WebKitFormBoundarym3TVRM3XmuMfHSO2
Content-Disposition: form-data; name="file"; filename="C2_2.1.0.1546_2018-05-25.pkg"
二进制数据
Content-Type: application/octet-stream

------WebKitFormBoundarym3TVRM3XmuMfHSO2

requests模拟一个表单数据的格式如下:files = {‘name’: (<filename>, <file object>,<content type>, <per-part headers>)}

那么模拟出来的数据就是  file_list = {“projectId”: (None,”-1″),”siteId”: (None,”-1″),”name”: (None,care_fw_name),”file”: (fw_pkg_name,file_data.read(),”application/octet-stream”)}

使用以二进制的形式来读取文件,放置到字典中,使用post(files=file_list)来进行提交,当然这个过程中很可能出错,所以需要抓取到正确的数据包

然后在抓取发送出去的数据包 来对比他们的不同之处,就能够看出哪些地方数据模拟错误了所以导致的失败,其次我发现发送的请求中headers中的

headers = {'Host':ip,
        'Connection':'keep-alive',
        'Referer':'http://%s/firmwares'%ip,
        'X-Auth-Token':token
        }
file_data = open(self.fw_pkg_path + fw_pkg_name,'rb')
file_list = {"projectId": (None,"-1"),"siteId": (None,"-1"),"name": (None,care_fw_name),"file": (fw_pkg_name,file_data.read(),"application/octet-stream")}
url = 'http://%s/firmwares'%ip
rsp = requests.post(url=url,headers=headers,files=file_list)

其次我发现headers中的Content-Type: multipart/form-data; boundary=—-WebKitFormBoundaryi7i2U34GooxOCnUm  不需要一起发送,发送之后表单格式反而错误了

multipart/form-data是基于post方法来传递数据的,并且其请求内容格式为Content-Type: multipart/form-data,用来指定请求内容的数据编码格式。另外,该格式会生成一个boundary字符串来分割请求头与请求体的,具体的是以一个boundary=${boundary}来进行分割

form-data格式一般是用来进行文件上传的。使用表单上传文件时,必须让

表单的 enctype 等于 multipart/form-data,因为该值默认值为application/x-www-form-urlencoded