在使用 Python 发送 HTTP POST 请求时(无论是使用 requests
还是 aiohttp
),json
和 data
参数有明确的区别和使用场景。理解这些区别对正确构建请求至关重要。
关键区别
特性 | json 参数 |
data 参数 |
---|---|---|
内容类型 | 自动设置为 application/json |
需要手动设置(默认是 application/x-www-form-urlencoded ) |
数据处理 | 自动序列化 Python 对象为 JSON | 需要手动序列化 |
使用场景 | API 请求(JSON-RPC, RESTful API) | 表单提交、文件上传、自定义格式 |
编码 | UTF-8 | 取决于内容类型 |
易用性 | 更简单(自动处理) | 需要更多手动工作 |
- 何时使用
data
参数: 使用场景:
-
表单提交(HTML 表单数据):
python
form_data = {"username": "john", "password": "secret"} response = requests.post("https://example.com/login", data=form_data)
-
文件上传:
python
files = {"file": open("report.pdf", "rb")} response = requests.post("https://example.com/upload", files=files)
-
发送原始文本(非 JSON):
python
xml_data = "<user><name>John</name></user>" response = requests.post("https://example.com/api", data=xml_data, headers={"Content-Type": "application/xml"})
-
多部分表单数据:
python
from aiohttp import FormData form = FormData() form.add_field("username", "john") form.add_field("avatar", open("avatar.jpg", "rb"), filename="avatar.jpg", content_type="image/jpeg") async with session.post(url, data=form) as response:
-
自定义内容类型:
python
custom_data = "custom format data" response = requests.post("https://example.com/api", data=custom_data, headers={"Content-Type": "text/plain"})
2. 何时使用 json
参数
使用场景:
-
当 API 期望接收 JSON 格式的数据时(大多数现代 API 使用 JSON)
-
当需要发送结构化数据(字典、列表等)
-
当 API 文档指定请求体应为 JSON
示例:
python
import requests
data = {"name": "John", "age": 30}
response = requests.post("https://api.example.com/users", json=data)
在 aiohttp 中:
python
async with session.post(url, json=params) as response:
优点:
-
自动设置
Content-Type: application/json
头 -
自动将 Python 对象序列化为 JSON
-
简化代码
3. 最佳实践建议
-
推荐使用
json=params
:python
response = requests.post(url, headers=headers, json=params, timeout=60)
-
更简洁
-
更安全(自动处理序列化)
-
自动设置正确的 Content-Type
-
-
如果使用
data
,必须手动序列化:python
response = requests.post(url, headers=headers, data=json.dumps(params), timeout=60)
-
确保传递的是字符串,不是字典, 手动将`params`字典序列化为JSON字符串,然后通过`data`参数发送
-
确保设置了正确的 Content-Type
-
-
避免使用
data=params
:-
这总是错误的,除非您确实想发送表单数据, 这会将`params`字典编码为`application/x-www-form-urlencoded`格式(即表单数据),而不是JSON。
-
对于 JSON API,会导致服务器解析错误
-