为何出现‘Failed to decode JSON object’错误?curl传参问题解析
首先,咱们先拆解一下你能正常运行的curl请求为什么没问题:
- 你明确指定了
Content-Type: application/json头,告诉服务器要接收的是JSON格式数据 - 用单引号
'包裹了整个JSON字符串,避免shell把双引号"或者大括号{}解析成特殊语法(比如shell会把未包裹的双引号当成命令边界,把大括号当成通配符展开) -d参数直接发送原始字符串,没有额外编码
而另一种curl请求失败,大概率是踩了以下几个坑之一,咱们逐个排查:
1. JSON字符串没有正确包裹,导致shell解析破坏了格式
如果你的错误请求是类似这样的:
curl -X POST --header 'Content-Type: application/json' 'http://127.0.0.1:5000/api/add' -d {"API_KEY":"cJRuOJyD2QdJpFpugf1QwrROKEuhSX80cRGLW6hoAC0", "ip":"127.0.0.1", "port":"4260"}
问题出在没有用单引号包裹JSON。shell会把{"API_KEY":"xxx"}里的双引号当成命令的分隔符,把大括号当成通配符去匹配当前目录下的文件,最终服务器收到的是被截断或者乱掉的字符串,自然无法解析成JSON。
2. 错误使用了--data-urlencode参数
如果你用了--data-urlencode代替-d:
curl -X POST --header 'Content-Type: application/json' 'http://127.0.0.1:5000/api/add' --data-urlencode '{"API_KEY":"xxx", ...}'
这个参数会把JSON里的特殊字符(比如双引号、冒号)进行URL编码,服务器收到的会是类似%7B%22API_KEY%22%3A%22xxx%22%2C...%7D这样的字符串,而不是原始JSON,request.get_json()自然无法解码。
3. 缺少Content-Type: application/json头(即使你用了force=True)
虽然request.get_json(force=True)会忽略请求头,强制尝试解析JSON,但如果你的请求发送的是表单编码的数据(比如没设置Content-Type时,curl默认用application/x-www-form-urlencoded),那-d参数会把JSON转换成键值对格式(比如{API_KEY:cJRuOJyD2QdJpFpugf1QwrROKEuhSX80cRGLW6hoAC0, ip:127.0.0.1, port:4260}被解析成多个表单字段),服务器拿到的根本不是JSON字符串,解析必然失败。
4. 错误使用了-F(表单上传)参数
如果你的错误请求用了-F参数来发送数据:
curl -X POST 'http://127.0.0.1:5000/api/add' -F 'data={"API_KEY":"xxx", ...}'
这会发送multipart/form-data格式的请求,JSON被包裹在表单字段data里,request.get_json()只会尝试解析请求体的原始内容,而不会去提取表单字段,所以也会报错。
验证方法
你可以给错误的请求加上-v参数(verbose模式),查看实际发送的请求头和请求体:
curl -v -X POST ... 你的错误请求 ...
对比正常请求的输出,重点看:
Content-Type头是否正确- 请求体的内容是否是完整的、未被修改的JSON字符串
内容的提问来源于stack exchange,提问作者Ciasto piekarz

