requests.Request 中参数data与json的区别
requests.Request使用参数data传值
-
当使用data传值时,入参为object类型,在发送前,request将参数前置处理,在body中处理成格式为k1=v1&k2=v2 格式,content_type:application/x-www-form-urlencoded
import requests
import json
if __name__ == '__main__':
playload={
"person":json.dumps({
"name":"Milton",
"age": "18"
})
}
resp = requests.post("http://localhost:8000/rftester/dd_msg/",data=playload)
# resp = requests.post("http://localhost:8000/rftester/dd_msg/", json=json.dumps(playload))
预处理格式如下:
content_type:application/x-www-form-urlencoded
data body: person={"name": "Milton", "age": "18"}
这种情况下,服务端可以通过各个key将参数提取,如
person = request.POST.get("person")
。
-
注意:当如上字典多层嵌套时,只能解析到第一层,value值必须为字符串,否则会解析出错,如下
import requests
import json
if __name__ == '__main__':
playload={
"person":{
"name":"Milton",
"age": "18"
}
}
resp = requests.post("http://localhost:8000/rftester/dd_msg/",data=playload)
# resp = requests.post("http://localhost:8000/rftester/dd_msg/", json=json.dumps(playload))
预处理后,格式如下:
content_type:application/x-www-form-urlencoded
data body: person=name&person=age
这种情况,服务端解析,会解析不到预期的入参,请注意!!!
requests.Request使用参数json传值
-
当request使用json传值时,入参为json字符串,在发送前,request将参数前置处理,在body中处理成格式为json字符串,content_type:application/json
import requests
import json
if __name__ == '__main__':
playload={
"person":{
"name":"Milton",
"age": "18"
}
}
# resp = requests.post("http://localhost:8000/rftester/dd_msg/",data=playload)
resp = requests.post("http://localhost:8000/rftester/dd_msg/", json=json.dumps(playload))
print(resp.text)
预处理格式如下:
content_type:application/json
json body: "{\"person\": {\"name\": \"Milton\", \"age\": \"18\"}}"
这种情况,服务端直接解析body,可以解析出合法json字符串,可以转换成对象。如:
body=json.loads(request.body)
修改源码,使得使用data传参时,支持解析嵌套字典。
找到源码位置:site-packages\requests\models.py
将_encode_params方法修改如下:
@staticmethod
def _encode_params(data):
"""Encode parameters in a piece of data.
Will successfully encode parameters when passed as a dict or a list of
2-tuples. Order is retained if data is a list of 2-tuples but arbitrary
if parameters are supplied as a dict.
"""
if isinstance(data, (str, bytes)):
return data
elif hasattr(data, 'read'):
return data
elif hasattr(data, '__iter__'):
result = []
for k, vs in to_key_val_list(data):
if isinstance(vs, basestring) or not hasattr(vs, '__iter__'):
vs = [vs]
for v in vs:
if v is not None:
result.append(
(k.encode('utf-8') if isinstance(k, str) else k,
v.encode('utf-8') if isinstance(v, str) else v))
if isinstance(vs,dict):
result.append((k.encode('utf-8') if isinstance(k, str) else k,
complexjson.dumps(vs).encode('utf-8')))
return urlencode(result, doseq=True)
else:
return data
测试结果如下:
import requests
import json
if __name__ == '__main__':
playload={
"person":{
"name":"Milton",
"age": "18"
},
"address":"GZ"
}
requests.Request()
resp = requests.post("http://localhost:8000/rftester/dd_msg/",data=playload)
预处理参数如下:
content_type:application/x-www-form-urlencoded
data body: person={"name": "Milton", "age": "18"}&address=GZ
通过以上修改源码后,data参数已经可以支持嵌套多层字典!!!