CURL简介⚓︎
curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思。
它的功能非常强大,命令行参数多达几十种。如果熟练的话,完全可以取代 Postman 这一类的图形界面工具。
本文介绍它的主要命令行参数,作为日常的参考,方便查阅。
不带有任何参数时,curl 就是发出 GET 请求。
$ curl https://www.example.com
上面命令向www.example.com发出 GET 请求,服务器返回的内容会在命令行输出。
命令行基础知识⚓︎
-A⚓︎
-A参数指定客户端的用户代理标头,即User-Agent。curl 的默认用户代理字符串是curl/[version]。
$ curl -A 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36' https://google.com
上面命令将User-Agent改成 Chrome 浏览器。
$ curl -A '' https://google.com
上面命令会移除User-Agent标头。
也可以通过-H参数直接指定标头,更改User-Agent。
$ curl -H 'User-Agent: php/1.0' https://google.com
-b⚓︎
-b参数用来向服务器发送 Cookie。
$ curl -b 'foo=bar' https://google.com
上面命令会生成一个标头Cookie: foo=bar,向服务器发送一个名为foo、值为bar的 Cookie。
$ curl -b 'foo1=bar;foo2=bar2' https://google.com
上面命令发送两个 Cookie。
$ curl -b cookies.txt https://www.google.com
上面命令读取本地文件cookies.txt,里面是服务器设置的 Cookie(参见-c参数),将其发送到服务器。
-c
-c参数将服务器设置的 Cookie 写入一个文件。
$ curl -c cookies.txt https://www.google.com
上面命令将服务器的 HTTP 回应所设置 Cookie 写入文本文件cookies.txt。
-d
-d参数用于发送 POST 请求的数据体。
$ curl -d'login=emma&password=123'-X POST https://google.com/login
# 或者
$ curl -d 'login=emma' -d 'password=123' -X POST https://google.com/login
使用-d参数以后,HTTP 请求会自动加上标头Content-Type : application/x-www-form-urlencoded。并且会自动将请求转为 POST 方法,因此可以省略-X POST。
-d参数可以读取本地文本文件的数据,向服务器发送。
$ curl -d '@data.txt' https://google.com/login
上面命令读取data.txt文件的内容,作为数据体向服务器发送。 --data-urlencode
--data-urlencode参数等同于-d,发送 POST 请求的数据体,区别在于会自动将发送的数据进行 URL 编码。
$ curl --data-urlencode 'comment=hello world' https://google.com/login
上面代码中,发送的数据hello world之间有一个空格,需要进行 URL 编码。
-e
-e参数用来设置 HTTP 的标头Referer,表示请求的来源。
curl -e 'https://google.com?q=example' https://www.example.com
上面命令将Referer标头设为https://google.com?q=example。
-H参数可以通过直接添加标头Referer,达到同样效果。
curl -H 'Referer: https://google.com?q=example' https://www.example.com
-F
-F参数用来向服务器上传二进制文件。
$ curl -F '[email protected]' https://google.com/profile
上面命令会给 HTTP 请求加上标头Content-Type: multipart/form-data,然后将文件photo.png作为file字段上传。
-F参数可以指定 MIME 类型。
$ curl -F '[email protected];type=image/png' https://google.com/profile
上面命令指定 MIME 类型为image/png,否则 curl 会把 MIME 类型设为application/octet-stream。
-F参数也可以指定文件名。
$ curl -F '[email protected];filename=me.png' https://google.com/profile
上面命令中,原始文件名为photo.png,但是服务器接收到的文件名为me.png。
-G
-G参数用来构造 URL 的查询字符串。
$ curl -G -d 'q=kitties' -d 'count=20' https://google.com/search
上面命令会发出一个 GET 请求,实际请求的 URL 为https://google.com/search?q=kitties&count=20。如果省略--G,会发出一个 POST 请求。
如果数据需要 URL 编码,可以结合--data--urlencode参数。
$ curl -G --data-urlencode 'comment=hello world' https://www.example.com
-H
-H参数添加 HTTP 请求的标头。
$ curl -H 'Accept-Language: en-US' https://google.com
上面命令添加 HTTP 标头Accept-Language: en-US。
$ curl -H 'Accept-Language: en-US' -H 'Secret-Message: xyzzy' https://google.com
上面命令添加两个 HTTP 标头。
$ curl -d '{"login": "emma", "pass": "123"}' -H 'Content-Type: application/json' https://google.com/login
上面命令添加 HTTP 请求的标头是Content-Type: application/json,然后用-d参数发送 JSON 数据。
-i
-i参数打印出服务器回应的 HTTP 标头。
$ curl -i https://www.example.com
上面命令收到服务器回应后,先输出服务器回应的标头,然后空一行,再输出网页的源码。
-I
-I参数向服务器发出 HEAD 请求,然会将服务器返回的 HTTP 标头打印出来。
$ curl -I https://www.example.com
上面命令输出服务器对 HEAD 请求的回应。
--head参数等同于-I。
$ curl --head https://www.example.com
-k
-k参数指定跳过 SSL 检测。
$ curl -k https://www.example.com
上面命令不会检查服务器的 SSL 证书是否正确。
-L
-L参数会让 HTTP 请求跟随服务器的重定向。curl 默认不跟随重定向。
$ curl -L -d 'tweet=hi' https://api.twitter.com/tweet
--limit-rate
--limit-rate用来限制 HTTP 请求和回应的带宽,模拟慢网速的环境。
$ curl --limit-rate 200k https://google.com
上面命令将带宽限制在每秒 200K 字节。
-o
-o参数将服务器的回应保存成文件,等同于wget命令。
$ curl -o example.html https://www.example.com
上面命令将www.example.com保存成example.html。
-O
-O参数将服务器回应保存成文件,并将 URL 的最后部分当作文件名。
$ curl -O https://www.example.com/foo/bar.html
上面命令将服务器回应保存成文件,文件名为bar.html。
--compressed
curl允许您要求HTTP和HTTPS服务器提供数据的压缩版本,然后在到达时对其进行自动解压缩.在带宽比CPU更有限的情况下,这将帮助您在更短的时间内接收更多的数据.
HTTP压缩可以使用两种不同的机制来完成,一种被认为是"正确的方法",另一种是每个人实际使用的方法,并且是广泛流行的方法! 压缩HTTP内容的常用方法是使用 Content-Encoding标题. curl使用--compressed选项做到这点:
curl --compressed http://example.com/
启用此选项后(如果服务器支持它),它将以压缩方式传递数据,curl将在保存数据或将其发送到stdout之前对其进行解压缩.这通常意味着,作为用户,除了可能注意到更快的传输之外,您实际上看不到或体验不到压缩.
这个--compressed选项要求使用支持的压缩算法之一进行内容编码压缩.还有稀罕的 Transfer-Encoding 方法,它是为自动方法创建的,但从未真正被广泛采用.您可以加--tr-encoding告诉curl请求传输编码压缩:
curl --tr-encoding http://example.com/
理论上,没有任何东西可以阻止您在同一命令行中使用这两者,但是在实践中,您可能会遇到,当要求以两种不同方式进行压缩时,一些服务器会感到有点混乱.只挑一个通常比较安全.
--raw
当--raw使用的时候,它禁用内容或传输编码的所有内部HTTP解码,而是让curl传递未更改的原始数据.
如果您正在编写某种中间软件,并且希望将内容传递给另一个HTTP客户端,并让它进行解码,则通常使用这种方法.
-s
-s参数将不输出错误和进度信息。
$ curl -s https://www.example.com
上面命令一旦发生错误,不会显示错误信息。不发生错误的话,会正常显示运行结果。
如果想让 curl 不产生任何输出,可以使用下面的命令。
$ curl -s -o /dev/null https://google.com
-S
-S参数指定只输出错误信息,通常与-s一起使用。
$ curl -s -o /dev/null https://google.com
上面命令没有任何输出,除非发生错误。
-u
-u参数用来设置服务器认证的用户名和密码。
$ curl -u 'bob:12345' https://google.com/login
上面命令设置用户名为bob,密码为12345,然后将其转为 HTTP 标头Authorization: Basic Ym9iOjEyMzQ1。
curl 能够识别 URL 里面的用户名和密码。
$ curl https://bob:[email protected]/login
上面命令能够识别 URL 里面的用户名和密码,将其转为上个例子里面的 HTTP 标头。
$ curl -u 'bob' https://google.com/login
上面命令只设置了用户名,执行后,curl 会提示用户输入密码。
-v
-v参数输出通信的整个过程,用于调试。
$ curl -v https://www.example.com
--trace 和 --trace-ascii
有时-v是不够的.特别是,当您想要存储包括实际传输的数据的完整流时.
对于curl使用的HTTPS、FTPS或SFTP等协议进行加密文件传输的情况,其他网络监视工具(如Wireshark或tcpdump)将无法为您轻松地完成这项工作.
为此,curl提供了另外两个选项,而不是使用-v.
--trace [filename]将在给定的文件名中保存完整的跟踪.您也可以使用'-'(减号),来将其传递到stdout,而不是文件名.你会这样使用它:
$ curl --trace dump http://example.com
完成后,有一个dump文件,它可以相当大.在这种情况下,'dump'文件的最先的15行看起来如下:
== Info: Rebuilt URL to: http://example.com/
== Info: Trying 93.184.216.34...
== Info: Connected to example.com (93.184.216.34) port 80 (#0)
=> Send header, 75 bytes (0x4b)
0000: 47 45 54 20 2f 20 48 54 54 50 2f 31 2e 31 0d 0a GET / HTTP/1.1..
0010: 48 6f 73 74 3a 20 65 78 61 6d 70 6c 65 2e 63 6f Host: example.co
0020: 6d 0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 63 m..User-Agent: c
0030: 75 72 6c 2f 37 2e 34 35 2e 30 0d 0a 41 63 63 65 url/7.45.0..Acce
0040: 70 74 3a 20 2a 2f 2a 0d 0a 0d 0a pt: */*....
<= Recv header, 17 bytes (0x11)
0000: 48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d HTTP/1.1 200 OK.
0010: 0a .
<= Recv header, 22 bytes (0x16)
0000: 41 63 63 65 70 74 2d 52 61 6e 67 65 73 3a 20 62 Accept-Ranges: b
0010: 79 74 65 73 0d 0a ytes..
每一个发送和接收的字节,都以十六进制数字单独显示.
如果你认为十六进制不起作用,你可以试试.--trace-ascii
[filename]取而代之,当然也接受stdout的"-",这使得跟踪的最先15行看起来像:
== Info: Rebuilt URL to: http://example.com/
== Info: Trying 93.184.216.34...
== Info: Connected to example.com (93.184.216.34) port 80 (#0)
=> Send header, 75 bytes (0x4b)
0000: GET / HTTP/1.1
0010: Host: example.com
0023: User-Agent: curl/7.45.0
003c: Accept: */*
0049:
<= Recv header, 17 bytes (0x11)
0000: HTTP/1.1 200 OK
<= Recv header, 22 bytes (0x16)
0000: Accept-Ranges: bytes
<= Recv header, 31 bytes (0x1f)
0000: Cache-Control: max-age=604800
--trace-time
该选项以高清晰的时间显示所有 verbose/trace 输出到打印行.它与-v / --verbose选项以及--trace和--trace-ascii规则一致.
一个例子可以是这样的:
$ curl -v --trace-time http://example.com
23:38:56.837164 * Rebuilt URL to: http://example.com/
23:38:56.841456 * Trying 93.184.216.34...
23:38:56.935155 * Connected to example.com (93.184.216.34) port 80 (#0)
23:38:56.935296 > GET / HTTP/1.1
23:38:56.935296 > Host: example.com
23:38:56.935296 > User-Agent: curl/7.45.0
23:38:56.935296 > Accept: */*
23:38:56.935296 >
23:38:57.029570 < HTTP/1.1 200 OK
23:38:57.029699 < Accept-Ranges: bytes
23:38:57.029803 < Cache-Control: max-age=604800
23:38:57.029903 < Content-Type: text/html
---- snip ----
每一行都是以小时为单位:分钟:秒,然后在秒后的是微秒数.
-x
-x参数指定 HTTP 请求的代理。
$ curl -x socks5://james:[email protected]:8080 https://www.example.com
上面命令指定 HTTP 请求通过myproxy.com:8080的 socks5 代理发出。
如果没有指定代理协议,默认为 HTTP。
$ curl -x james:[email protected]:8080 https://www.example.com
上面命令中,请求的代理使用 HTTP 协议。
-X
-X参数指定 HTTP 请求的方法。
$ curl -X POST https://www.example.com
上面命令对https://www.example.com发出 POST 请求。
-#
curl还具有一种可供选择的更简单的进度表.-# / --progress-bar. 正如长名称所暗示的,它替代显示了传输,变成进度条.
有时,当要求curl传输数据时,它不能计算出所请求的操作的总大小,并且随后使得进度表包含更少的细节,并且它不能,例如对传输时间做出预测等.
单位
进度表每秒显示字节和字节.
它还将使用后缀表示较大数量的字节,使用1024基本系统,因此1024是1千字节(1K),2048是2K等.curl支持这些:
| 后缀 | 数量 | 名字 |
|---|---|---|
| K | 2^10 | kilobyte |
| M | 2^20 | megabyte |
| G | 2^30 | gigabyte |
| T | 2^40 | terabyte |
| P | 2^50 | petabyte |
使用 H:MM:SS 显示 时间,分钟和秒.
进度表图例子
进度表的存在是,为了向用户展示一些实际正在发生的事情.输出中的不同字段具有以下含义:
% Total % Received % Xferd Average Speed Time Curr.
Dload Upload Total Current Left Speed
0 151M 0 38608 0 0 9406 0 4:41:43 0:00:04 4:41:39 9287
从左到右:
| 标题 | 意思 |
|---|---|
| % | 完成转移的百分比 |
| 合计-Total | 全部预期转移的总规模(如果已知) |
| % | 下载完成百分比 |
| 收到-Received | 当前下载字节数 |
| % | 上传完成百分比 |
| Xferd | 当前上传的字节数 |
| 平均下载速度-Average Speed Dload | 到目前为止,整个下载的平均传输速度,每秒字节数 |
| 平均上传速度-Average Speed Upload | 到目前为止整个上传的平均传输速度,每秒字节数 |
| 时间总和 Total | 期望完成操作的时间, HH:mm:SS表示数小时、分和秒 |
| 当前时间 Time Current | 从传输开始的时间过去,在HH:mm:SS符号数小时、分钟和秒. |
| 剩下的时间 Time Left | 预期完成时间,在HH:mm:SS符号数小时,分钟和秒 |
| 当前速度 Curr.Speed | 最后5秒的平均传输速度(当然,传输的前5秒基于更少的时间)是每秒的字节数 |
参考链接