5月28日 01:27

cURL 中 -d 和 --data 有什么区别?

-d 和 --data 是什么关系?

-d--data 是同一个参数的短格式和长格式,功能完全等价,没有任何行为差异。

bash
# 下面两条命令完全等价 curl -d "name=value" https://api.example.com curl --data "name=value" https://api.example.com

cURL 的大多数参数都有这种短/长格式对应关系,比如 -X--request-H--header。选择哪种写法纯属个人偏好:命令行简短操作用 -d,脚本中为了可读性用 --data

cURL 有哪些数据发送方式?

-d 只是 cURL 数据发送家族中的一个。不同参数对应不同的数据处理逻辑和 Content-Type:

参数数据处理方式默认 Content-Type典型场景
-d / --data发送数据,@ 读取文件并去除回车换行application/x-www-form-urlencoded表单提交、API 调用
--data-ascii-d 完全相同application/x-www-form-urlencoded明确语义时使用
--data-binary发送原始数据,@ 读取文件不做任何处理不自动设置二进制文件、保留换行的文本
--data-urlencode自动对特殊字符做 URL 编码application/x-www-form-urlencoded参数含空格或特殊字符
--data-raw原样发送,@ 不被解析为文件路径application/x-www-form-urlencoded数据内容本身含 @ 符号
-F / --formmultipart/form-data 编码multipart/form-data文件上传、混合表单
--json发送 JSON,自动设置 Content-Typeapplication/jsonREST API JSON 交互

-d 和 -F 的核心区别是什么?

这是面试高频追问点。-d 发送的是整体编码的请求体,-F 发送的是分段编码的请求体:

bash
# -d:整个请求体作为一个 URL 编码字符串 curl -d "name=张三&age=25" https://api.example.com/form # 请求体:name=张三&age=25 # Content-Type: application/x-www-form-urlencoded # -F:每个字段单独编码,用 boundary 分隔 curl -F "name=张三" -F "file=@photo.jpg" https://api.example.com/upload # Content-Type: multipart/form-data; boundary=----WebKitFormBoundary...

简单记忆:纯键值对用 -d,涉及文件上传用 -F。两者不能混用——如果同时指定,cURL 只会使用后出现的那个。

如何发送 JSON 数据?

-d 配合手动设置 Content-Type,或者直接用 --json(cURL 7.82.0+):

bash
# 方式一:-d + 手动设置 Header(兼容性最好) curl -X POST https://api.example.com/users \ -H "Content-Type: application/json" \ -d '{"name":"张三","age":25}' # 方式二:--json(7.82.0+,自动设置 Content-Type) curl --json '{"name":"张三","age":25}' https://api.example.com/users

注意:-d 不会自动转义或编码 JSON 中的特殊字符。如果 JSON 数据来自用户输入或文件,务必确保格式合法:

bash
# 从文件读取 JSON curl -X POST https://api.example.com/users \ -H "Content-Type: application/json" \ -d @payload.json

--data-binary 和 -d 读取文件有什么不同?

这是另一个容易踩坑的点。当用 @ 从文件读取数据时,-d 会静默去除回车符和换行符,--data-binary 则原样发送:

bash
# 准备一个包含换行的文件 # data.txt 内容: # line1 # line2 # line3 # -d 读取文件:换行被去除,数据变成 "line1line2line3" curl -d @data.txt https://api.example.com # --data-binary 读取文件:换行完整保留 curl --data-binary @data.txt https://api.example.com

发送 JSON、XML、二进制文件时,永远用 --data-binary 而不是 -d,否则数据可能被静默破坏。

--data-urlencode 和 --data-raw 什么时候用?

bash
# --data-urlencode:参数值含空格或特殊字符时 curl --data-urlencode "query=hello world!" https://api.example.com/search # 实际发送:query=hello%20world%21 # --data-raw:数据内容本身包含 @ 符号,不想被解释为文件路径 curl --data-raw "@channel notify" https://api.example.com/webhook # 发送的就是字面量 @channel notify,不会去找叫 channel 的文件

多个 -d 参数如何处理?

多次使用 -d 时,cURL 会用 & 将各段拼接起来:

bash
curl -d "name=张三" -d "email=zhangsan@example.com" https://api.example.com/form # 等价于 curl -d "name=张三&email=zhangsan@example.com" https://api.example.com/form

也可以混合使用不同数据参数,但要注意各自的编码规则:

bash
curl -d "title=测试" \ --data-urlencode "content=Hello World!" \ --data-binary @attachment.pdf \ https://api.example.com/mixed

常见踩坑点

1. 使用 -d 就隐含了 POST 请求

-d 会自动将请求方法设为 POST,不需要额外写 -X POST。如果你同时写了 -X GET -d "data",cURL 会发送一个带 body 的 GET 请求——这在大多数服务端会被忽略或拒绝。

2. Content-Type 需要自己管

-d 默认设置 application/x-www-form-urlencoded。如果你要发 JSON 却忘记加 -H "Content-Type: application/json",服务端可能按表单解析导致 400 错误。

3. @ 符号的双重含义

-d @filename 读取文件内容,-d @- 从标准输入读取。如果你的数据本身包含 @,必须用 --data-raw

4. -d 和 -F 不能混用

一个请求中只能选一种数据提交方式。如果两者都写了,cURL 只认后出现的那个,前面的会被静默忽略。

标签:cURL