为什么HTTP POST请求体需要在Python中加入JSON? [英] Why does HTTP POST request body need to be JSON enconded in Python?
问题描述
在玩外部API时遇到了这个问题。我将我的身体数据作为字典直接发送到请求中并且收到400个错误:
I ran into this issue when playing around with an external API. I was sending my body data as a dictionary straight into the request and was getting 400 errors:
data = {
"someParamRange": {
"to": 1000,
"from": 100
},
"anotherParamRange": {
"to": True,
"from": False
}
}
当我添加一个json.dumps换行,它可以工作:
When I added a json.dumps wrap, it works:
data = json.dumps({
"someParamRange": {
"to": 1000,
"from": 100
},
"anotherParamRange": {
"to": True,
"from": False
}
})
我不完全理解为什么会这样是必要的,因为字典和JSON对象在语法上是相同的。有人可以帮我理解幕后发生的事情吗?
I don't entirely understand why this is necessary, as dictionaries and JSON objects are syntactically identical. Can someone help me understand what is going on behind the scenes here?
为了完整性,这是我的标题:
For completeness, here are my headers:
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
I didn't mention this earlier but now I feel that it may be relevant. I am using the Python Requests library, and another post seems to suggest that you should never have to encode parameters to a request object: https://stackoverflow.com/a/14804320/1012040
无论GET / POST是否你再也不需要编码参数,它只需要一个字典作为一个参数并且很好。
"Regardless of whether GET/POST you never have to encode parameters again, it simply takes a dictionary as an argument and is good to go."
似乎不需要序列化?
我的要求对象:
response = requests.post(url, data=data, headers=headers)
推荐答案
显然,您的API需要JSON编码而非表格编码数据。当您将 dict
作为 data
参数传递时,数据将采用表单编码。当你传递一个字符串(比如 json.dumps
的结果)时,数据不是表格编码的。
Apparently your API requires JSON-encoded and not form-encoded data. When you pass a dict
in as the data
parameter, the data is form-encoded. When you pass a string (like the result of json.dumps
), the data is not form-encoded.
从请求文档中考虑此引用:
Consider this quote from the requests documentation:
通常,您希望发送一些表单编码数据 - 很像HTML表单。为此,只需将字典传递给data参数即可。在发出请求时,您的数据字典将自动进行表单编码。
Typically, you want to send some form-encoded data — much like an HTML form. To do this, simply pass a dictionary to the data argument. Your dictionary of data will automatically be form-encoded when the request is made.
有很多次您希望发送非表单编码的数据。如果你传入一个字符串而不是一个字典,那么这些数据将直接发布。
There are many times that you want to send data that is not form-encoded. If you pass in a string instead of a dict, that data will be posted directly.
例如,GitHub API v3接受JSON编码的POST / PATCH数据:
For example, the GitHub API v3 accepts JSON-Encoded POST/PATCH data:
>>> import json
>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}
>>> r = requests.post(url, data=json.dumps(payload))
参考:
- http://www.w3.org/TR/html401/interact/forms.html#h-17.13.3.4
- http://docs.python-requests.org/en/latest/user/quickstart/#more-复杂的后请求
- http://www.w3.org/TR/html401/interact/forms.html#h-17.13.3.4
- http://docs.python-requests.org/en/latest/user/quickstart/#more-complicated-post-requests
这篇关于为什么HTTP POST请求体需要在Python中加入JSON?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!