如何使用 curl 发送 POST 请求:完整参考

如何使用 curl 发送 POST 请求:完整参考

目前全球大约有 200 亿个 curl 实例正在运行。这个数字来自 curl 的创建者 Daniel Stenberg,他几乎独自一人维护着它。curl 被集成到路由器、汽车、卫星、智能电视、支撑大部分公共网络的 Linux 服务器以及所有主流的 LLM 运行时环境中。在这些实例发送的所有 HTTP 请求中,POST 请求承担了大部分工作。大多数开发者首次测试、调试或集成 API 时都会使用 curl POST 请求。

Postman 发布的《2025 年 API 现状报告》显示,REST 的采用率已达 93%。82% 的组织目前至少部分采用 API 优先的运营模式。无论何时创建、提交或向服务器传输数据,您都会使用 POST 请求。人工智能工作负载进一步加速了这一趋势。据 Postman 2024 年报告显示,2024 年人工智能相关的 API 流量增长了 73%,而且现在所有生命周期管理 (LLM) 提供商的文档都以 curl POST 代码片段作为标准的“首次调用”。

本指南详细介绍了使用 curl 发送 POST 请求的各种形式,从最简单的单行请求到调用真实的加密货币支付 API 的完整流程。目标是:提供可直接复制粘贴的实用指南,而不仅仅是阅读。无论是首次向服务器发送数据,还是在凌晨两点重建 webhook 处理程序,以下模式都能满足您的实际需求。

下表为简要版本。这是一份 curl 命令行选项及其用途速查表,涵盖了发送 POST 请求时最常用的选项。后续章节将逐一详细介绍。

旗帜它的作用当你伸手去拿它
`-X POST`,`--request POST`强制 HTTP 请求方法为 POST显式方法,或不常用的动词
`-d`,`--data`在请求体中发送数据,自动设置 POST表单字段、内联 JSON、简单有效负载
`--data-binary`发送文件或二进制数据时不去除换行符文件上传、大型 JSON、原始二进制数据
`--data-urlencode`在发送之前对值进行 URL 编码包含空格或特殊字符的值
`--json`发送数据时使用 `Content-Type: application/json` 和 `Accept: application/json` curl 7.82.0 或更高版本,JSON API
`-H`,`--header`添加自定义 HTTP 标头内容类型、授权、API 密钥
`-F`,`--form`发送包含表单字段或文件的 multipart/form-data 数据文件上传,HTML 样式表单
`-u`,`--user`发送 HTTP 基本身份验证凭据传统 API,简单的用户名-密码认证
`-i`,`--include`输出中包含响应头检查服务器响应
`-v`,`--verbose`打印完整的请求和响应,包括请求头。调试失败的 POST 请求

了解 curl POST 请求和 HTTP 方法

curl POST 请求实际上是一个 HTTP POST 请求,使用 POST 方法从命令行发出。curl 工具本身将其功能描述为“传输数据”,支持二十多种协议,HTTP 只是其中之一。POST 的含义是:这里有一些数据,请对它进行处理。有效负载(payload)位于请求体中,而不是 URL 中。正是由于这个特性,POST 可以处理资源创建、表单提交以及任何包含凭据的操作。GET 请求会将数据放在查询字符串中,所有代理和浏览器历史记录都可以看到这些数据。而 POST 请求则不会。

大多数教程都忽略了一个虽小但很有用的细节。传递 `-d` 参数后,curl 会自动切换到 POST 请求。显式指定的 `-X POST` 参数(用于指定自定义请求方法)是可选的。许多示例仍然包含它,因为在请求体旁边看到 `-X POST` 可以让人一眼看出请求意图。

PUT 和 POST 经常被混淆,因此有必要明确区分。PUT 用于替换已知位置的资源。POST 用于创建新资源或将数据发送到通用端点进行处理。

使用 curl 发送 POST 请求

curl POST 请求的基本语法和 -d 标志的实际应用

curl POST 请求最简形式为一行代码:

```

curl -d "username=arya&age=16" https://api.example.com/users

```

就是这样。POST 请求,form-urlencoded 格式的请求体,简单明了。`-d` 参数一举三得:它将有效负载塞进请求体,将请求方法改为 POST,并添加默认的 `Content-Type: application/x-www-form-urlencoded` 请求头。我通常还是会粘贴稍微详细一些的表单,因为 POST 请求的意图在代码审查中更容易理解:

```

curl -X POST -d "username=arya&age=16" https://api.example.com/users

```

网络传输的数据字节相同,请求参数也相同。选择团队认为更容易扫描的方式即可。`-d` 标志是命令行向服务器发送数据的主力军,它能处理后端开发人员使用 curl 时 90% 的操作:shell 调用、webhook 测试、Makefile 目标、GitHub Actions 步骤等等。

`-d` 的三个近亲。`--data-binary` 会保持字节完整;而普通的 `-d` 会去除换行符,并可能损坏二进制有效负载。`--data-urlencode` 会进行百分比编码:`--data-urlencode "name=I am Daniel"` 会被编码为 `name=I%20am%20Daniel`。`--data-raw` 是当值以 `@` 开头且 curl 不应读取文件时使用的选项。多个 `-d` 标志会用 `&` 连接。这适用于表单,但绝对不适用于 JSON。

最后还有一点需要注意:引号。用单引号将有效载荷括起来,可以防止 shell 解析 `$` 或反斜杠。如果忘记这样做,你可能会在凌晨两点还在纳闷为什么你的 POST 数据丢失了一半。

这些细节至关重要,因为 curl 本身是全球测试最严格的 HTTP 客户端之一。Stenberg 在 2025 年 12 月的回顾报告中统计了当年的八个版本,共发布了九个 CVE 漏洞,所有漏洞的严重程度均为低或中。共有 2179 个活跃测试用例,比一年前增加了 232 个。2024 年 12 月发布的 8.11.1 版本修复了 CVE-2024-11053 漏洞(利用 netrc 和重定向漏洞泄露凭据)。截至 2026 年 4 月底,当前稳定版本为 curl 8.20.0。版本低于 7.82.0 的用户仍然没有 `--json` 参数,只能使用旧的三参数模式。

使用 curl 发送 JSON 数据时,请使用 --json 或 -H 参数。

2026 年,JSON 将成为 REST API 的通用语言。使用 curl 发送 POST 请求有两种方法。具体使用哪种方法完全取决于机器上安装的 curl 版本。

经典的三旗模式,从 CentOS 6 开始即可在所有版本中使用:

```

curl -X POST \

-H "Content-Type: application/json" \

-d '{"title":"Tea","quantity":2}' \

https://api.example.com/orders

```

现代速记功能,自 curl 7.82.0 版本(2022 年 3 月)起可用:

```

curl --json '{"title":"Tea","quantity":2}' https://api.example.com/orders

```

`--json` 标志执行三项操作:设置 `Content-Type: application/json`;设置 `Accept: application/json`;发送请求体。它还支持请求体拼接:多次传递 `--json` 标志,请求体将拼接在一起。这在将 JSON 数据块通过管道传输到流式端点时非常有用。

对于存储在文件中的 JSON 数据,请在文件路径前加上 `@` 前缀。当 JSON 对象过大而无法直接粘贴到邮件中,或者数据被纳入版本控制系统,或者数据由其他脚本生成时,从文件中发布数据就成为标准模式:

```

curl -X POST -H "Content-Type: application/json" -d @order.json https://api.example.com/orders

curl --json @order.json https://api.example.com/orders

```

第二种模式从名为 `order.json` 的文件中读取数据,并发送包含所有正确标头的数据。对于大型或可能包含二进制数据的 JSON 内容,`--data-binary @file.json` 是更安全的选择。它不会去除换行符,也不会解释特殊字符,而是将原始二进制数据发送到期望接收字节而不是表单字段的端点。第三种模式通过 `-d @-` 从标准输入读取数据。当需要将另一个命令的输出直接通过管道传递给 curl POST 请求时,这种模式非常方便。

下表将四种常见的 JSON 格式与单个端点对应起来:

图案命令何时使用
直列式,经典`-X POST -H "Content-Type: application/json" -d '{"k":"v"}'`最大程度的兼容性,支持任何 curl 版本
直列式,现代`--json '{"k":"v"}'` curl 7.82.0 或更高版本,语法最简洁
从文件中,安全`-X POST -H "..." -d @payload.json`有效载荷保存在版本控制中
从文件读取,二进制安全`-X POST -H "..." --data-binary @payload.json`大文件,包含换行符的有效载荷

这比以往任何时候都更加重要。所有主流的生命周期管理 (LLM) 提供商——OpenAI、Anthropic、Mistral、Google——都在其 API 文档中提供了一个 curl POST 示例,其格式与此完全相同。人工智能驱动的流量在 2024 年使 API 调用总量增加了 73%(Postman 数据)。curl 现在已成为“如何调用此端点”的权威参考。

使用 curl 发送 POST 请求

Content-Type、标头以及 curl 的假设

大多数“415 不支持的媒体类型”响应都源于缺少一个请求头。使用 `-d` 参数时,curl 会在请求中悄悄地添加 `Content-Type: application/x-www-form-urlencoded` 标签。如果发送的 JSON 请求体没有使用 `-H "Content-Type: application/json"` 或 `--json` 参数,就会收到 415 错误。没有警告,只有直接的拒绝。

其他元数据也随请求体一起发送:例如 Content-Length、Authorization 标头以及用于追踪的 X-Request-Id。正确获取这些元数据是 API 集成成功的一半。JSON 对象本身反而是比较容易的部分。

`-H` 参数用于添加自定义请求头。可根据需要重复使用。请求头名称不区分大小写,但值区分大小写。调试配置错误的 POST 请求的最快方法是:使用 `-v` 参数运行一次,读取请求行,并与 API 文档进行比对。十有八九,错误会在几秒钟内显现出来。

还有两点需要注意。curl 会根据请求体的大小自动设置 Content-Length,你很少需要手动修改它。`Accept: application/json` 告诉服务器以 JSON 格式而不是 HTML 格式回复。你可以添加一个 `-H` 参数来实现这一点,或者使用 `--json` 参数,它会同时设置 Content-Type 和 Accept 参数。

使用 curl POST -F 上传表单数据和文件

对于包含文件的 HTML 格式表单数据,正确的标志是 `-F`。它会生成一个 `multipart/form-data` 请求。这与 `-d` 默认的表单 URL 编码内容类型不同,也代表着不同的思维模式。一些简短的教程经常将两者混淆,从而导致实际的错误。

每个字段只能使用一次 `-F`。纯文本字段:

```

curl -F "name=Arya" https://api.example.com/submit

```

文件上传:

```

curl -F "file=@/path/to/image.png" https://api.example.com/upload

```

`@` 前缀告诉 curl 从磁盘读取文件并将其内容包含在请求正文中。curl 会自动从文件名检测 MIME 类型;必要时可以显式覆盖它:

```

curl -F "[email protected];type=image/png" https://api.example.com/upload

```

多个 `-F` 标志可以将多个字段或文件打包到一个请求中:

```

curl -F "title=Holiday" -F "[email protected]" -F "[email protected]" https://api.example.com/album

```

对于不带 multipart 包装器的原始文件内容(例如向流式端点发送 JSON 文件或二进制 blob 时),请使用 `--data-binary @file.bin` 参数。这样会将文件字节原封不动地作为请求体发送,并带有您显式设置的 Content-Type。

curl POST 请求的身份验证方式:基本身份验证、Bearer 身份验证、API 密钥

2026 年,三种身份验证方式几乎可以涵盖所有 REST API。基本身份验证(用户名加密码,以 base64 编码形式包含在标头中):

```

curl -u "myuser:mypass" -X POST -d "..." https://api.example.com/login

```

Bearer 令牌(包括所有 OAuth 颁发的凭证在内的大多数现代 API 都使用)都位于自定义的 Authorization 标头中:

```

curl -H "Authorization: Bearer $TOKEN" --json '{"q":"hello"}' https://api.example.com/query

```

API密钥通常位于特定于服务的标头中:

```

curl -H "X-API-Key: $PLISIO_KEY" --json @invoice.json https://api.plisio.net/api/v1/invoices/new

```

凭据应来自环境变量或密钥管理器,切勿直接在脚本中输入。为什么?GitGuardian 发布的《2025 年密钥泄露状况报告》显示,2024 年有 2380 万个新的密钥泄露到 GitHub 公共服务器上,比 2023 年增长了 25%。其中超过 90% 的密钥在泄露五天后仍然有效。curl 脚本中的内联凭据是造成这些泄露的主要原因之一。下文的安全部分将介绍相关工作流程。

curl POST 请求的实际示例:Plisio 支付 API

没有实际示例的参考文档只是理论。下面的 curl POST 请求通过 Plisio 的 REST API 生成加密货币支付发票。Plisio 收取 0.5% 的固定费用;而信用卡处理商通常收取 2-4% 的费用。Plisio 支持三十多种加密货币,并为十九个电子商务平台提供集成。

为什么加密货币 API 可以作为练习目标?2025 年,稳定币的实际经济交易量约为 28 万亿美元。Chainalysis 预测,自 2023 年以来,其复合年增长率 (CAGR) 将达到 133%。据商业研究公司 (The Business Research Company) 的数据,2025 年加密货币支付网关市场规模接近 20 亿美元,预计 2026 年将达到 23.9 亿美元。BitPay、Coinbase Commerce、Plisio:随便选一个。与任何现代网关集成的第一步几乎都是使用 curl POST 请求。

创建新发票所需的最小调用语句:

```

curl -X POST https://api.plisio.net/api/v1/invoices/new \

-H "Content-Type: application/json" \

-H "授权:Bearer $PLISIO_API_KEY" \

-d '{

"source_currency": "USD",

"source_amount": 49.99,

"order_number": "INV-1042",

"currency": "BTC",

"email": "[email protected]",

"order_name": "Annual subscription"

}'

```

成功调用会返回 HTTP 201 状态码。响应体是一个 JSON 对象:包含生成的发票 ID、客户付款的 `invoice_url`、目标钱包地址和到期时间戳。接下来,可以使用 `jq` 函数提取所需的字段:

```

... | jq '.data.invoice_url'

```

这就是整个模式。只需替换端点和有效负载,其格式即可直接应用于 BitPay 付款、Coinbase Commerce 结账或 Stripe 付款意图。标志位保持不变,只有 JSON 数据会改变。

调试 curl POST 请求:-v、--trace、errors

POST 请求失败是一个调试难题。盲目重试是最糟糕的做法。命令行上的四个选项可以满足您的大部分需求。

`-v` 会打印请求行、每个请求头和响应状态。这是你首先会用到的标志。`--trace-ascii -` 功能更强大:它会将整个会话(包括 POST 请求的主体)输出到标准输出。使用 `curl -i` 可以将响应头内联到主体上方。而 `-w "%{http_code}\n"` 则只输出 HTTP 状态码,这在编写针对 API 的 CI 检查脚本时非常有用。

关于您最常遇到的状态码。400:服务器解析了您的请求,但拒绝了有效负载。401:缺少或无效的身份验证标头。415:内容类型错误。500:服务器在处理您的输入时崩溃。每个状态码都排除了特定的层级,这相当于在第一次失败时运行 `-v` 命令的一半价值。

curl POST 安全:API 密钥、密钥和泄露

所有参考文献都略过了这一部分。而每份事件事后分析报告都提到了它。2024年12月:美国财政部数据泄露事件追溯到泄露的BeyondTrust API密钥。这正是生产脚本中`-H "Authorization: Bearer ..."`标头里所包含的那种凭证。

这种防御方法并不华丽。从环境变量中读取令牌。将它们存储在密钥管理器中,例如 AWS Secrets Manager、HashiCorp Vault 或 1Password CLI。在提交前运行 `gitleaks` 或 `trufflehog`。轮换所有曾经存在于 shell 历史记录中的令牌。这些方法都不令人兴奋,但它们都有效。对于后端开发人员来说,在 2026 年养成将这些方法应用到你发出的每一个 curl POST 请求中,是最重要的习惯。

任何问题?

两种格式。多部分上传(HTML 表单网络格式):`curl -F "file=@/path/to/file.png" https://api.example.com/upload`。原始二进制文件,无包装:`curl --data-binary @file.bin -H "Content-Type: application/octet-stream" https://api.example.com/raw`。`@` 表示 curl 从磁盘读取文件。

curl 7.82.0(2022 年 3 月)及更高版本:`curl --json `{"key":"value"}` https://api.example.com`。在旧版本中,使用三参数模式:`curl -X POST -H "Content-Type: application/json" -d `{"key":"value"}` https://api.example.com`。JSON 文件已存在?请在参数前添加 `@`:`--json @payload.json` 或 `-d @payload.json`。

我不会说哪个“更好”。curl 在 shell 比 GUI 更胜一筹的场景下更胜一筹:例如一次性调用、持续集成任务以及任何通过 SSH 访问的任务。Postman 则在保存集合、并排比较差异以及团队协作方面更胜一筹。我两者都保留了下来。

打开 shell,粘贴 `curl -X POST -d "field=value" https://api.example.com/endpoint`,然后按回车键。如果端点需要 JSON 格式,请添加 `-H "Content-Type: application/json"`,或者如果您使用的是 curl 7.82.0 或更高版本,则使用 `--json`。输出将打印到标准输出(stdout),可供 `jq` 使用。

GET 请求本身即可生效。POST 请求会在第二个 `-d`、`--data`、`--data-binary`、`--data-urlencode`、`--F` 或 `--json` 参数进入请求体时生效。其他任何请求(PATCH、DELETE、PROPFIND)都需要 `-X` 参数,因为这些请求都没有“快捷”标志。

在终端中使用 `curl -X POST`(或任何数据发送标志)会得到这样的结果。这个命令告诉服务器“接收此请求并执行某些操作”。我通常用它来测试 REST 端点、重放生产环境中失效的 webhook,或者在部署后立即对 Lambda 函数进行“烟雾”测试。

Ready to Get Started?

Create an account and start accepting payments – no contracts or KYC required. Or, contact us to design a custom package for your business.

Make first step

Always know what you pay

Integrated per-transaction pricing with no hidden fees

Start your integration

Set up Plisio swiftly in just 10 minutes.