为什么HTTP POST请求体需要在Python中加入JSON?

acp*_*eon 19 python http python-requests

在玩外部API时遇到了这个问题.我将我的身体数据作为字典直接发送到请求中,并且收到了400个错误:

data = {
  "someParamRange": {
    "to": 1000, 
    "from": 100
  }, 
  "anotherParamRange": {
    "to": True, 
    "from": False
  }
}
Run Code Online (Sandbox Code Playgroud)

当我添加一个json.dumps包装时,它可以工作:

data = json.dumps({
  "someParamRange": {
    "to": 1000, 
    "from": 100
  }, 
  "anotherParamRange": {
    "to": True, 
    "from": False
  }
})
Run Code Online (Sandbox Code Playgroud)

我不完全理解为什么这是必要的,因为字典和JSON对象在语法上是相同的.有人可以帮我理解幕后发生的事情吗?

为了完整性,这是我的标题:

headers = {'API-KEY': 'blerg', 'Accept-Encoding': 'UTF-8', 'Content-Type': 'application/json', 'Accept': '*/*', 'username': 'user', 'password': 'pwd'}
Run Code Online (Sandbox Code Playgroud)

编辑:

我之前没有提到这个,但现在我觉得它可能是相关的.我正在使用Python Requests库,另一篇文章似乎建议你永远不必将参数编码到请求对象:https://stackoverflow.com/a/14804320/1012040

"无论GET/POST是否你再也不需要编码参数,它只需要一个字典作为参数,并且很好."

好像序列化似乎不是必要的?

我的请求对象:

response = requests.post(url, data=data, headers=headers)
Run Code Online (Sandbox Code Playgroud)

Rob*_*obᵩ 35

显然,您的API需要JSON编码而不是表单编码数据.当您将dictin作为data参数传递时,数据将进行表单编码.传递字符串(如结果json.dumps)时,数据不是表单编码的.

请考虑请求文档中的引用:

通常,您希望发送一些表单编码数据 - 非常类似于HTML表单.为此,只需将字典传递给data参数即可.在请求发出时,您的数据字典将自动进行表单编码.

您有很多次要发送未经表单编码的数据.如果传入字符串而不是dict,则会直接发布该数据.

例如,GitHub API v3接受JSON编码的POST/PATCH数据:

>>> import json
>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}

>>> r = requests.post(url, data=json.dumps(payload))
Run Code Online (Sandbox Code Playgroud)

参考文献:

  • 这对我来说不起作用.我不得不添加以下标题:headers = {''Content-Type':'application/json'} (6认同)
  • 请求库在[版本2.4.2](http://docs.python-requests.org/en/latest/user/quickstart/#more-complicated-post-requests)中添加了一个“ json”参数。现在您可以直接传递字典对象`requests.post(url,json = data,headers = headers)` (3认同)