python中发送form-data数据

前言

今天调试一个接口的时候,接口要求是form-data格式,python中我使用的requests的库,一般是直接使用data参数发送,但是结果从和postman等工具请求的结果不一样

过程

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import requests

url = "https://api.cloudflare.com/client/v4/accounts/aaa/storage/kv/namespaces/aab/values/cdd"

payload = {
'value': '{"Cookie":"__pus=6qBMw"}',
'metadata': '{}'
}

headers = {
'X-Auth-Key': '2323',
'X-Auth-Email': '23@gmail.com'
}

response = requests.request("PUT", url, headers=headers, data=payload)

print(response.request.body)
print(response.request.headers)

很简单的一段代码,发送个put请求,请求体是data,data里是连个参数,一个value,一个metadata,发送后,用工具查询,返回的结果是编码payload 的,这个接口正常应该只返回一个json,就是value的值!

我用postman试着put请求了一下,然后get,结果是正确的,返回的就是value里的json值,难道是我自己写错了,然后我用postman里的代码生成,找到python requests的请求代码,原封不动的粘到vscode里,然后运行后,发现没有任何变化,还是错误的结果!

解决

一度怀疑难道是python这个requests库有bug,但是应该不能啊,用这个库的人那么多,有问题应该早就被发现并解决了,然后我怀疑是不是参数的问题,我打印了body和headers,最终发现了问题,请求头中的content-type居然是x-www-urlencoded,参数无疑直接直接被编码成类似:a=1&b=1这种了

然后我问了下copilot,给我检查下我这么写对不对,然后它回答了正确答案,说:不应该放到data里,而应该放到files里,正确代码如下:

1
response = requests.request("PUT", url, headers=headers, files=payload)

运行后,果然没问题了!

结语

网上大部分搜索到的都是说放到data里,也不知道是误导人,还是python后来改过,这也算是学到了!