Python Requests包中data和json参数的区别

156 投票
3 回答
60563 浏览
提问于 2025-04-30 23:36

在Python的Requests库中,datajson这两个参数有什么区别呢?

官方文档上看,似乎没有说得很清楚。

比如这段代码:

import requests
import json
d = {'a': 1}
response = requests.post(url, data=json.dumps(d))

( 注意我们在这里把dict转换成了JSON哦 ☝️! )

...和这段代码:

import requests
import json
d = {'a': 1}
response = requests.post(url, json=d)

有什么不同吗?

后者会不会自动把Content-Type这个HTTP头设置为application/json呢?

暂无标签

3 个回答

4

根据我的经验,建议使用 json 字段来传递字典,而不是把字典放在 data 字段里。

再次强调,这只是我的经验,我并没有深入研究代码,但看起来 requests 库在处理 json 数据时比单纯使用 json.dumps 更聪明。当我在 data 字段使用 json.dumps 时,遇到过几次服务器(FastAPI)返回“值不是有效的字典”的错误。改用 json 字段后,这些问题就解决了。

补充:今天我看了一下代码。如果你使用 json 参数,requests 库似乎只是设置了 Content-Type 并进行了一些处理:

from .compat import json as complexjson
content_type = 'application/json'
body = complexjson.dumps(json)
if not isinstance(body, bytes):
    body = body.encode('utf-8')

requests.compat 中,json 只是:

try:
    import simplejson as json
except ImportError:
    import json

... 所以我真的搞不懂为什么手动使用 data 参数有时候就会失败。¯\_(ツ)_/¯

89

截至2021年12月,关于使用datajson的区别,requests文档已经非常清楚了

(我们对此做了一点小贡献 - 我的PR和你们的点赞证明这曾经是个问题。谢谢大家!)


附言

这并没有直接回答提问者的问题,但如果第一段代码稍微不同一些:

import requests
import json
d = {'a': 1}
response = requests.post(url, data=d)

(注意这里的dict d没有被转换成JSON字符串!)

如果第二段代码保持不变(为了完整性复制一下):

import requests
import json
d = {'a': 1}
response = requests.post(url, json=d)

...那么结果会有很大不同。

第一段代码会生成一个请求,内容类型设置为application/x-www-form-urlencoded,数据格式是这样的:"a=1"

而第二段代码会生成一个请求,内容类型设置为application/json,数据格式实际上是这样的:{"a": 1} - 这是一个JSON字符串。

130

为了回答我自己的问题,看来我上面给出的两个例子其实是做同样的事情。而且使用 json 参数确实会把请求头中的 content-type 设置为 application/json。在我上面第一个例子中使用 data 参数时,content-type 就需要手动设置了。

撰写回答