curl发送JSON POST的最小可用命令是什么?

最小可用命令包含三个必要元素-X POST指定方法、-H "Content-Type: application/json"声明body格式、-d携带JSON字符串。三者缺一,服务端就有可能按表单或纯文本解析请求体。

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"keyword":"电动牙刷","page":1}' \
  https://api.example.com/search

命令参数的作用如下:

参数作用是否必需
-X POST显式指定HTTP方法使用-d时curl会隐式设为POST,但建议显式写
-H "Content-Type: ..."告诉服务端body格式JSON场景必需
-d / --data携带请求体必需
-H "Accept: ..."告诉服务端希望的响应格式建议加,避免服务端返回错误格式

一个更完整的最小命令示例:

curl -X POST \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"keyword":"电动牙刷","page":1}' \
  https://api.example.com/search

-d参数的一个隐性行为要注意:默认使用Content-Type: application/x-www-form-urlencoded,即使body内容是JSON,服务端也会按表单解析。因此-H "Content-Type: application/json"不是可选项,而是必选项。

另外一个容易被忽略的细节是body内的单双引号。上面示例把JSON字符串用单引号包裹'{"k":"v"}',这样双引号可以直接写而不用转义,最省心。如果shell不支持单引号或body含shell变量,就要改用双引号包裹并对内部双引号做\"转义,出错概率会高很多。网站采集器调用第三方查询接口时,建议统一约定用单引号包裹body写法,避免团队成员踩坑。


JSON请求体来源有几种写法,各自适合什么场景?

JSON请求体有四种主流来源:内联字符串、文件读取、标准输入管道、heredoc块。四种写法适合不同的body体积、动态性、调试便利度需求。

来源方式命令写法适合场景
内联字符串-d '{"k":"v"}'body简短、静态、快速调试
文件读取-d @body.jsonbody较大、多次复用、版本化管理
标准输入管道-d @-body由上游程序动态生成
heredoc块-d @-<<EOF ... EOF脚本中拼接多行JSON、可读性优先

内联字符串:最短的写法,适合快速调试或body简短的场景。

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"keyword":"电动牙刷","page":1,"size":20}' \
  https://api.example.com/search

文件读取:body存在独立文件里,用@前缀引用。适合请求体较大、需要版本化管理、多次复用的场景。

# body.json 内容
# {"query":"电动牙刷","filters":{"price":{"min":100,"max":500}}}

curl -X POST \
  -H "Content-Type: application/json" \
  -d @body.json \
  https://api.example.com/search

标准输入管道:body由上游程序生成后通过管道传入,用@-表示从stdin读取。适合脚本化调度、body动态拼接的场景。

echo '{"keyword":"电动牙刷","timestamp":"'"$(date -u +%FT%TZ)"'"}' | \
  curl -X POST \
  -H "Content-Type: application/json" \
  -d @- \
  https://api.example.com/log

heredoc块:脚本中拼接多行JSON时可读性最佳,配合shell变量插值方便。

KEYWORD="电动牙刷"
curl -X POST \
  -H "Content-Type: application/json" \
  -d @- \
  https://api.example.com/search <<EOF
{
  "keyword": "$KEYWORD",
  "page": 1,
  "size": 20,
  "filters": {
    "category": "personal_care"
  }
}
EOF

四种写法的关键取舍是body来源与调试成本。网站采集器批量提交查询任务时-d @file最合适,body固定、可版本化管理;广告监测每分钟上报动态数据时管道或heredoc更灵活。日常联调建议先用内联字符串跑通,再切到文件或管道方式做批量化。

需要注意的是heredoc块里的shell变量插值行为——用<<EOF时shell会做变量替换和命令替换,用<<'EOF'加单引号时会保留字面量。如果body里既有shell变量又有原生美元符号,可以用\$转义单个美元符号,或者干脆分两段拼接。


中文和特殊字符怎么保证POST请求不乱码?

乱码问题的根源是字符编码不一致。curl本身不对body做编码转换,body是什么编码就发送什么编码。保证不乱码要满足三个条件:源文件UTF-8编码、Content-Type声明charset、shell环境LANG支持UTF-8。

第一步,确认源文件与shell环境为UTF-8:

# 查看 shell 语言环境
echo $LANG
# 期望输出:zh_CN.UTF-8 或 en_US.UTF-8

# 查看文件编码
file -bi body.json
# 期望输出:application/json; charset=utf-8

第二步,Content-Type显式声明charset:

curl -X POST \
  -H "Content-Type: application/json; charset=utf-8" \
  -d '{"keyword":"电动牙刷"}' \
  https://api.example.com/search

第三步,body中的特殊字符按JSON规范转义:

字符JSON转义写法说明
"\"body用单引号包裹时可直接写,用双引号包裹时要转义
\\\路径分隔符、正则表达式常用
换行\nJSON字符串内换行必须转义
Tab\t制表符
中文UTF-8原文或\uXXXX推荐UTF-8原文,可读性更好

一个包含转义的完整示例:

curl -X POST \
  -H "Content-Type: application/json; charset=utf-8" \
  -d '{"query":"关键词 with \"引号\"","path":"C:\\logs\\a.txt","note":"多行\n内容"}' \
  https://api.example.com/log

如果body来自变量拼接,用jq预先生成合法JSON是较稳妥的做法:

KEYWORD='关键词 with "引号"'
BODY=$(jq -n --arg kw "$KEYWORD" '{keyword: $kw, page: 1}')

curl -X POST \
  -H "Content-Type: application/json; charset=utf-8" \
  -d "$BODY" \
  https://api.example.com/search

jq -n --arg会自动处理转义,避免手动写\"时踩坑。舆情监测这类场景需要提交长文本给NLP API做分析,用jq预生成JSON能显著降低出错率。

除了jq,Python的json.dumps、Node的JSON.stringify都能在脚本中生成安全的JSON。选哪种取决于团队技术栈。核心原则是"永远不要手动拼接JSON字符串"——只要body里出现用户输入或外部变量,就用工具生成。手动拼接的隐患不仅是转义错误,还包括无效字符注入、编码错乱等更深层问题。


需要鉴权的接口,Authorization头怎么加?

主流API鉴权分四种:Bearer Token、Basic Auth、API Key放Header或Query、自定义签名。四种在curl中都通过-H携带对应头字段完成。

鉴权类型curl写法典型使用
Bearer Token-H "Authorization: Bearer <TOKEN>"OAuth 2.0、大部分SaaS API
Basic Auth-u user:pass-H "Authorization: Basic <base64>"老旧API、内部系统
API Key放Header-H "X-API-Key: <KEY>"大部分商业API
API Key放Query拼接到URL ?api_key=<KEY>简易API,不推荐生产使用

Bearer Token,OAuth 2.0体系里最常见:

TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"keyword":"电动牙刷"}' \
  https://api.example.com/search

Basic Auth,curl内置的-u更简洁,会自动做base64编码:

curl -X POST \
  -H "Content-Type: application/json" \
  -u "username:password" \
  -d '{"action":"query"}' \
  https://api.example.com/internal

API Key放Header,很多SaaS商业API的默认方式:

curl -X POST \
  -H "Content-Type: application/json" \
  -H "X-API-Key: sk_live_xxxxxxxxxxxxx" \
  -d '{"campaign_id":"C-2026-001"}' \
  https://api.example.com/ads/report

自定义签名,例如HMAC,需要预先计算签名后写进头:

TIMESTAMP=$(date -u +%s)
SIGNATURE=$(echo -n "$TIMESTAMP" | openssl dgst -sha256 -hmac "$SECRET_KEY" | awk '{print $2}')

curl -X POST \
  -H "Content-Type: application/json" \
  -H "X-Timestamp: $TIMESTAMP" \
  -H "X-Signature: $SIGNATURE" \
  -d '{"data":"..."}' \
  https://api.example.com/sign

鉴权头的三条常见坑

  • Token/Key不要写死在命令里,用环境变量或从secrets manager拉取,避免误提交到git
  • Bearer Token前的Bearer 空格不能省,一些服务端严格校验会返回401
  • Basic Auth的用户名密码含特殊字符时用-u user:pass比手写base64更稳,curl会自动处理

广告监测调用广告平台API这类场景,通常用API Key + HMAC签名双因子鉴权,签名部分可以封装成一个shell函数复用。


生产环境POST的超时、重试、大请求体怎么处理?

生产级POST请求要配置四类保护:连接超时、总超时、失败重试、大body专用参数。默认curl不设超时,网络波动时可能挂起,重试也需要显式开启。

场景参数推荐配置
连接超时--connect-timeout5-10秒
总超时--max-time30-60秒,视业务定
失败重试次数--retry3次
重试间隔--retry-delay从2秒起指数递增
重试触发条件--retry-connrefused--retry-all-errors视需求开
大body上传-T--data-binary @file避免-d对二进制做处理

一个覆盖生产保护参数的完整命令:

curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d @body.json \
  --connect-timeout 10 \
  --max-time 60 \
  --retry 3 \
  --retry-delay 2 \
  --retry-max-time 120 \
  --retry-all-errors \
  https://api.example.com/submit

大请求体的特殊处理-d默认会对body内容做换行符处理,即去掉\n,如果body是二进制或需要精确保留字节,用--data-binary

curl -X POST \
  -H "Content-Type: application/json" \
  --data-binary @large_body.json \
  https://api.example.com/upload

超过10MB的body推荐用-T,等价于HTTP PUT但很多API也接受,或分片上传接口。同时打开gzip压缩能显著减少传输量:

curl -X POST \
  -H "Content-Type: application/json" \
  -H "Content-Encoding: gzip" \
  --data-binary @<(gzip -c large_body.json) \
  https://api.example.com/upload

网站采集器批量提交查询任务时--retry-all-errors很有用,能覆盖连接错误、HTTP 5xx、超时等多种失败情形;舆情监测调用NLP API处理长文本时--max-time要放宽到60秒以上,避免正常处理被超时打断。


通过代理调用海外或内网API时命令怎么写?

curl通过代理调用API的核心参数是-x--proxy。支持HTTP、HTTPS、SOCKS4、SOCKS5四种协议,鉴权用--proxy-user

协议URL写法说明
HTTP代理-x http://host:port明文HTTP代理
HTTPS代理-x https://host:portcurl与代理之间也走HTTPS
SOCKS5-x socks5://host:port建议加h后缀让DNS在代理端解析
SOCKS5+DNS远程-x socks5h://host:port推荐,DNS通过代理走,避免DNS泄露

HTTP代理示例

curl -X POST \
  -H "Content-Type: application/json" \
  -x http://proxy.example.com:8080 \
  -d '{"keyword":"electric toothbrush"}' \
  https://api.example.com/search

代理需要鉴权时

curl -X POST \
  -H "Content-Type: application/json" \
  -x http://proxy.example.com:8080 \
  --proxy-user "username:password" \
  -d @body.json \
  https://api.example.com/search

SOCKS5代理,走DNS远程解析:

curl -X POST \
  -H "Content-Type: application/json" \
  -x socks5h://proxy.example.com:1080 \
  --proxy-user "username:password" \
  -d '{"keyword":"electric toothbrush"}' \
  https://api.example.com/search

代理配置的三条实用做法

  • 用环境变量而不是每条命令都写-xexport https_proxy=http://user:pass@proxy:8080
  • 内网某些域名要跳过代理时用--noproxy--noproxy "*.internal.com,localhost"
  • 排查代理是否生效用-v观察是否有Connected to proxy一行

海外API调用是代理最常见的使用场景之一。广告监测拉取海外广告平台数据、跨境物流信息查询走物流商官方API,都需要通过海外出口代理才能访问到目标地域的完整数据。

代理稳定性直接影响curl命令的成功率。生产环境建议把-x配合--connect-timeout--max-time一起用,代理不通时快速失败,避免拖垮整体任务调度。同时把代理鉴权凭证放到环境变量或密钥管理系统里,命令行只引用变量名,减少凭证泄露风险。


curl调试POST请求失败时可观测性怎么做?

curl的可观测性有三层-v看请求响应头、--trace-ascii看完整报文、-w看时序与状态。三层从粗到细,配合使用能覆盖90%以上的调试需求。

参数输出内容适合场景
-v--verbose请求头、响应头、连接过程大部分调试第一站
--trace-ascii <file>完整请求响应报文含body需要看服务端返回的详细body
-w--write-out自定义输出,含状态码、时间、大小生产监控、性能分析
-i响应含头部输出到stdout简单查看响应头
-o /dev/null丢弃响应body只关心时序或状态码

基础调试-v

curl -v -X POST \
  -H "Content-Type: application/json" \
  -d '{"keyword":"电动牙刷"}' \
  https://api.example.com/search

输出会包含请求行>和响应行<的每一行,一眼能看出鉴权是否发出、Content-Type是否正确、服务端返回什么状态码。

看完整报文--trace-ascii

curl --trace-ascii /tmp/curl.trace \
  -X POST \
  -H "Content-Type: application/json" \
  -d @body.json \
  https://api.example.com/submit

trace文件里能看到完整的请求body和响应body,适合排查服务端"400 Bad Request"但不知道body哪里错的场景。

生产监控与时序分析-w

curl -o /dev/null -s -w \
  'HTTP: %{http_code}\nTotal: %{time_total}s\nConnect: %{time_connect}s\nTTFB: %{time_starttransfer}s\nSize: %{size_download}\n' \
  -X POST \
  -H "Content-Type: application/json" \
  -d @body.json \
  https://api.example.com/submit

输出示例:

HTTP: 200
Total: 1.234s
Connect: 0.089s
TTFB: 0.923s
Size: 512

-w常用的可观测变量:

变量含义
%{http_code}HTTP响应状态码
%{time_total}请求总耗时
%{time_connect}TCP连接建立耗时
%{time_starttransfer}首字节返回耗时,即TTFB
%{size_download}响应body大小,单位字节
%{url_effective}实际请求的URL,含重定向后

网站采集器把curl当作快速探针使用时,-w的输出可直接接入监控系统,做请求成功率、延迟、体积的三维观测;广告监测的定时任务里加上-w能快速定位是TTFB高还是连接慢。


FAQ

Q:-d--data-binary的区别是什么?

-d会剥掉body里的\r\n换行符,适合发送单行JSON字符串。--data-binary会精确保留body的所有字节,适合发送二进制、多行JSON、或需要精确控制字节的场景。传JSON时如果body是格式化过的多行文本,用--data-binary更安全。

Q:curl POST JSON时收到400 Bad Request,怎么排查?

按四步排查:一看-v输出确认Content-Type是否为application/json;二用--trace-ascii看服务端返回的错误详情;三本地用jq . body.json验证JSON格式是否合法;四检查是否有BOM头或不可见字符,用file -bi body.json看编码是否为UTF-8。

Q:curl POST时需要维持cookie会话,怎么写?

-c cookies.txt保存服务端返回的cookie到文件,用-b cookies.txt在后续请求带上cookie。两个参数可以同时用,实现完整的会话保持。舆情监测这类需要登录态的场景常这样用。

Q:POST请求需要跟随重定向,命令怎么加?

-L--location。默认curl不跟随3xx重定向,加-L后会自动跟随。跟随重定向时如果原请求是POST,curl会根据3xx状态码类型决定是否保持POST方法——303改GET、307和308保持POST。要强制保持用--post301--post302--post303

Q:怎么在shell脚本中判断curl POST是否成功?

推荐用-o body -w "%{http_code}"分离body和状态码。示例:

STATUS=$(curl -o /tmp/resp.json -s -w "%{http_code}" \
  -X POST -H "Content-Type: application/json" \
  -d @body.json https://api.example.com/submit)

if [ "$STATUS" = "200" ]; then
  echo "OK"
else
  echo "Failed: $STATUS"
fi

这个模式比解析-v输出稳定。

Q:POST请求返回压缩响应比如gzip或deflate,怎么解压?

--compressed,curl会自动声明Accept-Encoding并对响应做解压。示例:curl --compressed -X POST -H "Content-Type: application/json" -d @body.json https://api.example.com/search。响应压缩率高的API比如返回大列表的搜索接口,加上后能显著减少传输时间。

Q:curl POST时如何跳过HTTPS证书校验?仅调试用

-k--insecure)。这个参数只在调试自签证书或过期证书的内部环境时用,生产环境严禁使用,会失去HTTPS的中间人防护。正确做法是把根证书通过--cacert导入。

青果网络代理IP - CTA Banner
点赞(54)
Twitter数据采集合规获取方案:API权限、法规边界与技术路径全解析
数据采集 API权限 HTTP代理 全球代理IP
2026-08-27

Twitter数据合规采集需要同时满足三层约束:平台服务条款、目标市场数据保护法规、技术实现合规性。官方API是合规基线,网页端公开数据采集需要在请求频率、数据用途、个人信息处理三个维度做合规设计,不同采集目的对应不同的合规路径。

IP池行业挑选应注意哪些?品牌规模、合规、可用率、纯净度基准
IP池 代理IP池 企业级代理 HTTP代理
2026-08-26

IP池挑选不是"参数榜"式的比大小。真正决定业务能否长期稳定跑下去的是四个基准:品牌规模的可核查维度、合规资质的完整度、可用率之外的稳定性衍生指标、IP纯净度的评估方法。本文拆解这四个基准各自的判断标准与落地权重。

PowerShell网页请求:Invoke-WebRequest教程
IP代理 SOCKS5代理 企业级代理 IP地址
2026-08-24

Invoke-WebRequest是PowerShell内置的HTTP客户端,覆盖GET/POST、代理、Cookie会话、TLS版本控制、错误重试五大能力。上手比curl慢一点,但在Windows运维、定时任务、日志采集场景优势明显。本文按"能用→稳定→长期跑"三档给出完整教程。

数据采集采购实录:某电商日均千万级请求实战
并发采集 合规采集 代理IP异常 IP代理
2026-08-21

某跨境电商从日均百万级采集扩容到千万级,踩过的坑集中在四个工程维度:IP调度架构、故障隔离机制、成本模型设计、合规治理。堆IP解决不了规模化问题,系统性的架构决策才是关键。

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部