Ubuntu环境下Curl发送JSON至API遇格式错误问题求助
Ubuntu下curl发送JSON更新库存API报错的解决方法
问题场景
在Windows环境中使用Invoke-WebRequest可以正常向机器库存API发送JSON更新请求,但在Ubuntu中执行curl命令时,频繁出现curl(3)(URL格式非法)和curl(6)(无法解析主机)错误,即使给JSON添加引号仍无法解决。
Windows正常执行的命令示例
$postHash = ConvertTo-Json(@{ "hostName" = $computerName; "macAddress" = $macAddress; "ipAddress" = $ipAddress; "pcModel" = $model; "diskType" = $diskType; "graphicsType" = $graphicsType; "serviceTag" = $serviceTag; "diskMode" = $diskMode; "wolMode" = $wolMode; "displayType" = $displayType; "displayServiceTag" = $displayServiceTag; "recDate" = $recDate; "sleepState" = $sleepState; }) Invoke-WebRequest -Method PUT -Body $postHash https://our_api.org/api/inventory/$macAddress/ -ContentType "application/json" -Headers @{"Authorization" = "Token 62d85f430210cd1a827bfdc34cd6c1fb1a64d1"} | Out-Null
Ubuntu下的错误命令及报错
user@ubuntu:~$ echo $json { "pcModel": "KAT12", "displayType": "DELL U2311H", "graphicsType": "Microsoft Remote Display Adapter", "displayServiceTag": "HV8XP08Q079L", "ipAddress": "172.16.4.194", "recDate": "2022-10-06 16:57:55", "serviceTag": "18LQ9X1;Diskwear:(4.91TBW ; 15393 Hours)", "wolMode": "lanwithpxeboot;CC:101010-0118ZH;os:Ubuntu", "sleepState": "disable", "macAddress": "90:B1:1C:8E:D5:11", "hostName": "CI-KR95-05", "diskMode": "raid", "diskType": "Samsung SSD 850 PRO 512GB;TBW+Hrs:(4.91TB;15393 HrH) ;Clock:3.4GHz;Max Clock:3.67GHz(108%);RAM:32GB" } user@ubuntu:~$ curl -k -L -X "PUT" -H "Accept: application/json" -H "Authorization: Token 62d85df90210cd1a827bc1518c4cd6c1fb1a64d1" "https://our_api.org/api/inventory/$macAddress/" -d $json {"hostName":["This field is required."],"pcModel":["This field is required."],"diskType":["This field is required."],"macAddress":["This field is required."],"serviceTag":["This field is required."],"diskMode":["This field is required."],"wolMode":["This field is required."],"sleepState":["This field is required."],"displayType":["This field is required."],"displayServiceTag":["This field is required."],"recDate":["This field is required."],"ipAddress":["This field is required."]}curl: (3) URL using bad/illegal format or missing URL curl: (6) Could not resolve host: "pcModel" ...(后续大量无法解析主机的报错)
添加引号后的尝试仍报错:
user@ubuntu:~$ curl --request PUT --header "Accept: application/json" --header "Authorization: Token 62d85df90210cd1a827bc1518c4cd6c1fb1a64d1" "https://our_api.org/api/inventory/$macAddress" -d "$value" curl: (3) URL using bad/illegal format or missing URL
错误原因分析
- 缺少Content-Type头:Windows命令中明确指定了
ContentType "application/json",但curl命令中遗漏了该头,导致API无法识别请求体为JSON格式,返回字段必填错误。 - Shell解析特殊字符:JSON中包含空格、分号等特殊字符,直接传递
$json时,Shell会将这些字符作为参数分隔符,把JSON拆分成多个独立参数,curl误将这些参数当作URL处理,引发无法解析主机的错误。即使使用双引号包裹,Shell仍会解析JSON内部的特殊字符(如分号、空格),导致格式混乱。
解决方法
方法1:指定Content-Type并使用单引号包裹JSON变量(适合无单引号的JSON)
如果JSON内容中不包含单引号,可以用单引号包裹变量,避免Shell解析内部特殊字符,同时添加Content-Type头:
curl -k -L -X PUT \ -H "Accept: application/json" \ -H "Authorization: Token 62d85df90210cd1a827bc1518c4cd6c1fb1a64d1" \ -H "Content-Type: application/json" \ "https://our_api.org/api/inventory/$macAddress/" \ -d '$json'
方法2:将JSON写入文件传递(最可靠,适合大JSON或含特殊字符的情况)
对于较大的JSON或包含复杂特殊字符的内容,将JSON写入文件后用curl读取,是最稳妥的方式:
- 先将JSON内容写入文件:
echo "$json" > inventory_update.json
- 使用curl读取文件发送请求:
curl -k -L -X PUT \ -H "Accept: application/json" \ -H "Authorization: Token 62d85df90210cd1a827bc1518c4cd6c1fb1a64d1" \ -H "Content-Type: application/json" \ "https://our_api.org/api/inventory/$macAddress/" \ --data-binary @inventory_update.json
--data-binary参数会原样读取文件内容,避免任何字符解析问题,适合大文件传输。
额外注意事项
- 确保
$macAddress变量在Shell中已正确赋值,若包含特殊字符需进行URL编码(可使用urlencode工具)。 - 若JSON中包含单引号,优先使用文件传递的方式,避免转义带来的麻烦。
- 测试时可直接替换
$macAddress为实际MAC地址,排查变量展开是否存在问题。
内容的提问来源于stack exchange,提问作者Andy McRae
相关产品推荐
相关产品推荐

