用 data 还是 json 取决于后端接收格式:data 用于表单(application/x-www-form-urlencoded),json 用于 JSON(application/json);传错导致 400 或字段为空。

requests.post 用 data 还是 json?看后端要什么格式
本质区别不是“哪个更高级”,而是发出去的数据体(body)长什么样、Content-Type 是什么。后端接口通常只认一种,错一个就 400 或字段收不到。
-
json=xxx自动把 Python 对象序列化成 JSON 字符串,设Content-Type: application/json -
data=xxx原样发——如果传的是 dict,requests 会自动urlencode成key=value&key2=value2,Content-Type 变成application/x-www-form-urlencoded - 如果
data传的是字符串或 bytes,就不会自动编码,Content-Type 也不自动设,得自己加headers
表单提交(HTML form)对应的是 data,不是 json
浏览器点「提交」按钮,默认就是 application/x-www-form-urlencoded 编码。后端框架(如 Flask 的 request.form、Django 的 request.POST)默认只从这个编码里取值。
- ✅ 正确:用
data={'username': 'alice', 'password': '123'}—— 后端能直接读到request.form['username'] - ❌ 错误:用
json={'username': 'alice', 'password': '123'}—— 后端request.form是空的,得去request.get_json()里找,但多数表单接口根本没开这个入口 - ⚠️ 特殊情况:有些前端用 AJAX 模拟表单但手动发 JSON,那后端就得配合改逻辑,这不是标准表单行为
Content-Type 不匹配时的典型错误现象
不是所有报错都写明“类型不对”,容易卡在“参数收不到”“字段为 None”“400 Bad Request”这种模糊反馈上。
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
- 后端是 Flask +
request.form,但你发了json=...→request.form为空,打印出来是ImmutableMultiDict([]) - 后端是 Django +
request.POST,你用json=...→request.POST是空QueryDict,request.body里倒是有 JSON 字符串,但不走 POST 解析流程 - 你用
data传了一个 dict,但后端期待 JSON → 收到一串 URL 编码字符串,比如user[name]=alice,解析失败 - 用
data传了 JSON 字符串但忘了设 headers → Content-Type 仍是默认的application/x-www-form-urlencoded,后端按表单解,自然乱码
想发 JSON 又绕不开表单逻辑?检查后端是否支持 multipart 或混合解析
极少数场景(比如上传文件+JSON元数据),后端可能用 multipart/form-data 包一层。这时候既不能纯 data(没法嵌套结构),也不能纯 json(不支持二进制)。但这种情况必须看接口文档,requests 本身不帮你自动切换。
立即学习“Python免费学习笔记(深入)”;
- 不要自己拼
data=json.dumps(...)+ 手动设Content-Type—— 和直接用json=...等价,还多写两行 - 不要对
data传的 dict 做json.dumps—— requests 会把它当普通对象再 urlencode 一次,结果变成%7B%22name%22%3A+%22alice%22%7D - 真要混用(比如带文件),老实用
files参数,JSON 字段放data里作为字符串键值,别碰json
最常被忽略的一点:很多调试者盯着 Python 代码改来改去,却没打开浏览器 DevTools 的 Network 标签页,对比「浏览器真实提交」和「requests 提交」的 Request Headers 和 Payload 差在哪——那个 Content-Type 和 body 的实际字节,才是唯一真相。

















