python - 为什么 HTTP POST 请求正文需要在 Python 中进行 JSON 编码?

标签 python http python-requests

我在使用外部 API 时遇到了这个问题。我将我的 body 数据作为字典直接发送到请求中,并收到 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)

最佳答案

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

考虑一下请求文档中的这句话:

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

引用:

关于python - 为什么 HTTP POST 请求正文需要在 Python 中进行 JSON 编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15694120/

相关文章:

Python 一个统计文件行数和字符数的函数

python - 使用 BeautifulSoup 当 Job 可用时提醒我

Python3 使用 Metaclass 创建 JSON 文件中定义的类

asp.net - IIS 只监听 127.0.0.1 而不是 0.0.0.0

http - 浏览器如何能够恢复下载?

json - 在 golang 中为 Places API 使用 HTTP 客户端,解码 JSON 和无效字符

rest - Django REST 框架 RequestsClient 内容类型

python - 当您只需要一个时,如何在 Pandas 数据框中按用户选择最小记录,同时考虑多个匹配项

python - 如何使用 requests 库从 http 请求中获取 IP 地址?

python - pygame.error : Failed loading libmpg123. dll:尝试访问无效地址