python requests post json_Python requests.post方法中的data与json参数差异

遇到问题

在用requests.post方法测试接口调用时,使用data参数得到Response 400结果;使用json参数得到Response 200。测试代码如下。

import requests

import json

url = "https://10.20.32.92:8834/scans"

accesskey = 'dc9ada34d59'

secretkey = 'f3b404a433fea25'

header = {

'X-ApiKeys': 'accessKey={accesskey};secretKey={secretkey}'.format(accesskey=accesskey, secretkey=secretkey),

'X-API-Token':'0FADA7F5-8903-4686-81F7-ECD0096628EA',

'Content-type': 'application/json',

'Accept': 'text/plain'

}

data = {

"uuid":"bbd4f805-3966-d464-b2d1-0079e2bcf",

"settings":{

"name":"testscan",

"enabled": "true",

"text_targets": "ip_list",

"agent_group_id": []

}

}

print(requests.post(url, headers=header, data=data, verify=False))

print(requests.post(url, headers=header, json=data, verify=False))

400与200含义

400 Bad Request --- The server cannot or will not process the request due to an apparent client error (e.g., malformed request syntax, size too large, invalid request message framing, or deceptive request routing).

200 OK --- Standard response for successful HTTP requests. The actual response will depend on the request method used. In a GET request, the response will contain an entity corresponding to the requested resource. In a POST request, the response will contain an entity describing or containing the result of the action.

data与json区别

从requests的官方文档解释中看出:

data用于发送form-encoded数据,类似HTML表单

json用于发送not form-encoded数据,例如发送字符串。

json参数将Content-Type改为application/json

json参数自动对传入的参数调用json.dumps()

从requests源码中的prepare_body函数中可看出针对json参数,修改了Content-Type以及调用json.dumps()的操作。

这样可能不能很好的理解这两个参数的区别,下面使用https://httpbin.org/post测试,代码如下:

import requests

import json

header = {

'Content-type': 'application/json'

}

data = {

"uuid":"test-uuid",

"settings":{

"name":"test-httpbin",

"enabled": "true",

"text_targets": "ip_list",

}

}

print('\n')

print('-- [ data = data ] -------------------------------------------')

r = requests.post("https://httpbin.org/post", data=data)

print(r.text)

print('\n')

print('-- [ data = json.dumps ] -------------------------------------------')

r = requests.post("https://httpbin.org/post", data=json.dumps(data))

print(r.text)

print('\n')

print('-- [ json = data ] -------------------------------------------')

r = requests.post("https://httpbin.org/post", json=data)

print(r.text)

执行结果如下:

-- [ data = data ] -------------------------------------------

{

"args": {},

"data": "",

"files": {},

"form": {

"settings": [

"name",

"enabled",

"text_targets"

],

"uuid": "test-uuid"

},

"headers": {

"Accept": "*/*",

"Accept-Encoding": "gzip, deflate",

"Content-Length": "67",

"Content-Type": "application/x-www-form-urlencoded",

"Host": "httpbin.org",

"User-Agent": "python-requests/2.22.0"

},

"json": null,

"url": "https://httpbin.org/post"

}

-- [ data = json.dumps ] -------------------------------------------

{

"args": {},

"data": "{\"uuid\": \"test-uuid\", \"settings\": {\"name\": \"test-httpbin\", \"enabled\": \"true\", \"text_targets\": \"ip_list\"}}",

"files": {},

"form": {},

"headers": {

"Accept": "*/*",

"Accept-Encoding": "gzip, deflate",

"Content-Length": "105",

"Host": "httpbin.org",

"User-Agent": "python-requests/2.22.0"

},

"json": {

"settings": {

"enabled": "true",

"name": "test-httpbin",

"text_targets": "ip_list"

},

"uuid": "test-uuid"

},

"url": "https://httpbin.org/post"

}

-- [ json = data ] -------------------------------------------

{

"args": {},

"data": "{\"uuid\": \"test-uuid\", \"settings\": {\"name\": \"test-httpbin\", \"enabled\": \"true\", \"text_targets\": \"ip_list\"}}",

"files": {},

"form": {},

"headers": {

"Accept": "*/*",

"Accept-Encoding": "gzip, deflate",

"Content-Length": "105",

"Content-Type": "application/json",

"Host": "httpbin.org",

"User-Agent": "python-requests/2.22.0"

},

"json": {

"settings": {

"enabled": "true",

"name": "test-httpbin",

"text_targets": "ip_list"

},

"uuid": "test-uuid"

},

"url": "https://httpbin.org/post"

}

从结果可看出data=json.dumps()与json=data是等价的。而它们与data=data的差异在于数据存放的字段不同。

data=data,数据存放在form字段中

json=data,数据存放在data和json字段中

由此可看出,使用requests.post方法中的data或json参数发送数据时,发送的数据被放到不同的键(form或data/json)下。具体从哪个键取数据,这就看接口的实现方式了。因此,若接口从data/json取数据,而调用requests.post方法时使用data参数发送数据,则会导致接口取出的数据为空,从而返回400状态码。

补充1:HTTP状态码分类

HTTP响应状态代码分为五个类别。第一位表示响应的类别,后两位没有分类作用。五个分类如下:

1xx informational response – the request was received, continuing process

2xx successful – the request was successfully received, understood and accepted

3xx redirection – further action needs to be taken in order to complete the request

4xx client error – the request contains bad syntax or cannot be fulfilled

5xx server error – the server failed to fulfill an apparently valid request

补充2:python字典和Json的区别

从字符串的表示规则上看,Python字典和JSON非常相似。但是Python字典本身是一个完整的数据结构,可实现其自己的所有算法。

json的key只能是字符串;Python字典的key可以是任何可hash对象

json的key可以是有序、重复的;Python字典的key不可以重复

json的key存在默认值undefined;Python字典key默认没有默认值

json的value只能是字符串、浮点数、布尔值或者null,或者它们构成的数组或者对象

json访问方式可以是[],也可以是.,遍历方式分in、of;dict的value仅可以下标访问

json的字符串强制双引号;Python字典的字符串可以单引号、双引号

json里只有数组;Python字典可以嵌套tuple

json:true、false、null;python:True、False、None

json中文必须是unicode编码,如"\u6211"

json的类型是字符串;Python字典的类型是字典

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值