为什么HTTP POST请求体需要在Python中进行JSON编码?

时间:2013-03-28 23:45:30

标签: python http python-requests

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

data = {
  "someParamRange": {
    "to": 1000, 
    "from": 100
  }, 
  "anotherParamRange": {
    "to": True, 
    "from": False
  }
}

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

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

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

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

headers = {'API-KEY': 'blerg', 'Accept-Encoding': 'UTF-8', 'Content-Type': 'application/json', 'Accept': '*/*', 'username': 'user', 'password': 'pwd'}

编辑:

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

“无论GET / POST是否你再也不需要编码参数,它只需要一个字典作为参数就可以了。”

似乎不需要序列化?

我的请求对象:

response = requests.post(url, data=data, headers=headers)

2 个答案:

答案 0 :(得分:33)

显然,您的API需要JSON编码而非表单编码数据。当您将dict作为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))

参考:

答案 1 :(得分:1)

虽然它们似乎是语法上的迭代,但是有一点不同:JSON是序列化对象的字符串表示;在这种情况下Python字典。在此示例中,您需要以字符串形式发送序列化数据,因此需要json.dumps来执行序列化。

修改

正如对问题的评论中所建议的那样,它与使用过的API有关,但是序列化必须在通过网络发送对象的某个地方完成。