为什么 HTTP POST 请求正文需要在 Python 中使用 JSON 编码? [英] Why does HTTP POST request body need to be JSON enconded in Python?

查看:21
本文介绍了为什么 HTTP POST 请求正文需要在 Python 中使用 JSON 编码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用外部 API 时遇到了这个问题.我将我的正文数据作为字典直接发送到请求中,但出现了 400 个错误:

data = {一些参数范围":{到":1000,来自":100},另一个参数范围":{到":对,来自":错误}}

当我添加一个 json.dumps 包装时,它起作用了:

data = json.dumps({一些参数范围":{到":1000,来自":100},另一个参数范围":{到":对,来自":错误}})

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

为了完整起见,这里是我的标题:

headers = {'API-KEY': 'bleg', 'Accept-Encoding': 'UTF-8', 'Content-Type': 'application/json', 'Accept': '*/*','用户名':'用户','密码':'密码'}

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

无论是 GET/POST,您都不必再次对参数进行编码,它只需要一个字典作为参数,就可以了."

好像不需要序列化?

我的请求对象:

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

解决方案

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

考虑请求文档中的引用:

<块引用><块引用>

通常,您希望发送一些表单编码数据 — 很像 HTML 表单.为此,只需将字典传递给 data 参数.发出请求时,您的数据字典将自动进行表单编码.

很多时候您想要发送非表单编码的数据.如果你传入的是字符串而不是字典,那么数据将被直接发布.

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

<预><代码>>>>导入json>>>url = 'https://api.github.com/some/endpoint'>>>有效载荷 = {'some': 'data'}>>>r = requests.post(url, data=json.dumps(payload))

参考:

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
  }
}

When I added a json.dumps wrap, it works:

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

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'}

EDIT:

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

"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."

Seems like serialization shouldn't be necessary?

My request object:

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

解决方案

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:

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.

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))

Refs:

这篇关于为什么 HTTP POST 请求正文需要在 Python 中使用 JSON 编码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆