Python requests迁移Postman multipart请求遇Content-Type不支持错误
问题:Python requests发送multipart/form-data时无法为JSON参数设置Content-Type
Postman中可正常运行的multipart/form-data请求,迁移到Python requests库时出现问题:仅能为file部分设置application/pdf类型,无法为JSON格式的input参数设置application/json类型,导致API返回错误Content type application/octet-stream not supported。
原始代码
import requests url = "{host}:{port}/{end_point}" payload = {'input': '{ \"name\": \"-\", \"name2\": \"-\", \"name3\": [\"-\", \"-\"]}'} files = [('file', ('contractFile.pdf', open('contractFile.pdf', 'rb'), 'application/pdf'))] headers = {'Authorization': 'Basic ---'} response = requests.request("POST", url, headers=headers, data=payload, files=files) print(response.text)
请求体要求
请求包含两部分:
- file:索赔模板PDF文件,需设置
Content-Type: application/pdf - input:JSON格式的附加输入数据,需设置
Content-Type: application/json
尝试过的无效方案
- 使用MultipartEncoder时写法错误,报错
Content-type ' not supported:
data = MultipartEncoder( fields={ 'input': ('{ some_json }', 'application/json'), 'file': ('contractFile.pdf', open('contractFile.pdf', 'rb'), 'application/pdf') })
- 单独设置全局
Content-Type请求头(如application/json、multipart/form-data;)无效 - 将
data参数改为json参数,API无法识别input参数
期望的请求格式
------WebKitFormBoundaryvwEtOpAEPX1EGWtN Content-Disposition: form-data; name="input"; filename="blob" Content-Type: application/json { JSON_BODY } ------WebKitFormBoundaryvwEtOpAEPX1EGWtN Content-Disposition: form-data; name="file"; filename="---" Content-Type: application/pdf ------WebKitFormBoundaryvwEtOpAEPX1EGWtN--
解决方案
将input参数以虚拟文件的形式加入files列表,指定对应的filename和Content-Type,让requests自动生成符合要求的multipart分块:
import requests import json url = "{host}:{port}/{end_point}" # 用json.dumps生成标准JSON字符串,避免手动转义 input_payload = json.dumps({ "name": "-", "name2": "-", "name3": ["-", "-"] }) # 把input当作虚拟文件,filename设置为"blob"(和Postman一致) files = [ ('input', ('blob', input_payload, 'application/json')), ('file', ('contractFile.pdf', open('contractFile.pdf', 'rb'), 'application/pdf')) ] headers = {'Authorization': 'Basic ---'} response = requests.post(url, headers=headers, files=files) print(response.text)
原理说明
- requests的
data参数会将普通表单字段默认标记为application/octet-stream或text/plain,不符合API对input参数的Content-Type要求 - 将input包装为虚拟文件后,requests会为该分块自动添加
Content-Disposition: form-data; name="input"; filename="blob"和Content-Type: application/json,与Postman的请求格式完全匹配
内容的提问来源于stack exchange,提问作者Resurrect1on
相关产品推荐
相关产品推荐

