Python requests发multipart/form-data报错,Postman同表单正常
问题根因与修正方案
核心错误点
- 手动硬编码
Content-Type: multipart/form-data请求头
multipart/form-data格式的请求头必须携带随机生成的boundary分隔符,用于切割请求体内不同的表单数据块,手动写死的纯multipart/form-data头完全缺失boundary参数,服务端无法解析请求结构,自然判定收到的不是合法的multipart数据。
requests库在处理multipart编码时,会自动生成携带正确boundary的Content-Type头,手动覆盖反而会破坏正确的请求逻辑。 - 传参逻辑完全不符合multipart编码要求
requests库中,直接将普通字典传入data参数时,默认会将数据序列化为application/x-www-form-urlencoded格式的键值对,根本不会生成multipart结构的请求体。
代码中传入的data还包含多层嵌套字典结构,本身也无法直接被序列化为合法的表单字段值。
可正常运行的修正代码
import requests import json url = 'https://merokirana.com/semantro-web-interface/query' # 构造所有multipart表单字段,嵌套的结构化值需按服务端要求转为可序列化的字符串 form_fields = { "@context": "http://semantro.com/", "@type": "KiranaSearch", "actionName": "listCategoryProducts", "pageLimit": json.dumps({ "@context": "http://semantro.com/", "@type": "PageProperty", "start": 0, "end": 24 }), "data": json.dumps({ "@context": "http://semantro.com/", "@type": "KiranaCategory", "identifier": "c5394d1d5c6c4cb8-adc77dd996876dba" }) } # 传入files参数触发requests的multipart编码流程,自动生成带正确boundary的请求头,无需手动设置Content-Type response = requests.post(url, files=form_fields) print(response.text)
常见踩坑提示
multipart/form-data头里的boundary是每次请求随机生成的,永远不要手动硬编码这个请求头- 请求体编码格式由传入的参数类型决定,仅修改请求头字符串不会改变实际请求体的编码逻辑:传纯字典给
data参数就会走urlencoded编码,传入files参数才会触发multipart编码 - Postman能正常发起请求的核心是,选择multipart/form-data格式时会自动生成带正确boundary的请求头,和上述代码的请求逻辑完全一致
内容的提问来源于stack exchange,提问作者Birat Bade Shrestha
相关产品推荐
相关产品推荐

