Python requests.post方法中的data与jso

2019-12-27  本文已影响0人  Gavin_c980

遇到问题

在用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含义

data与json区别

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

从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的差异在于数据存放的字段不同。

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

补充1:HTTP状态码分类

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

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

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

上一篇 下一篇

猜你喜欢

热点阅读