curl 介绍
curl
是一个命令行工具,用于在命令行界面中与各种协议(如HTTP、HTTPS、FTP等)进行数据传输。它常被用于发送和接收网络请求,是开发者在进行网络调试、API测试时非常有用的工具。
curl
支持的通信协议包括但不限于:FTP、FTPS、HTTP、HTTPS、TFTP、SFTP、Gopher、SCP、Telnet、DICT、FILE、LDAP、LDAPS、IMAP、POP3、SMTP和RTSP。此外,有些资料还提到了curl
支持RTMP、SMB、SMBS、IMAPS、POP3S和SMTPS等协议,这可能取决于curl
的版本和编译时的配置。
curl
不仅支持多种协议,还提供了丰富的功能,如SSL认证、HTTP POST、HTTP PUT、FTP上传、HTTP表单上传、代理支持、HTTP/2、cookies、用户名+密码认证等。这些功能使得curl
成为开发者在进行网络调试、API测试时的首选工具。
本篇博文主要介绍curl对HTTP协议的支持。
curl命令的常用参数及其作用
-X
或--request
:指定请求方法(如GET、POST、PUT等)。-d
或--data
:在POST或PUT请求中发送数据。-H
或--header
:自定义请求头。-o
或--output
:将响应输出到文件。-v
或--verbose
:显示详细的传输信息。-s
或--silent
:静默模式,不显示进度和错误消息。-L
或--location
:如果服务器返回重定向响应,则跟随重定向。-u
或--user
:指定用户名和密码,用于需要认证的服务。
基本的命令
发送GET请求
bash
代码解读
复制代码
$ curl http://www.baidu.com
发送POST请求
bash
代码解读
复制代码
$ curl -X POST -d "param1=value1¶m2=value2" http://www.baidu.com
curl 命令和参数详解
HTTP的方法
在每一个HTTP请求中,都有一个对应的方法,常用的方法有:GET、POST、HEAD和PUT。
如果在一个curl命令中不指定具体的方法,那么默认的就是使用GET方法。对于其它的方法,可以在curl命令中使用-X 指定:
bash
代码解读
复制代码
$ curl -X POST www.baidu.com
HTTP Response 的 Header 显示
在curl中,使用 -i 选项可以显示Response的Header信息,连同Body数据:
bash
代码解读
复制代码
$ curl -i www.baidu.com
终端上显示结果
xml
代码解读
复制代码
HTTP/1.1 200 OK Accept-Ranges: bytes Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform ....... Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/ <!DOCTYPE html> <!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> ....... </body> </html>
使用 -I 选项可以只显示Response的Header信息,不显示content信息:
css
代码解读
复制代码
$ curl -I www.baidu.com
保存响应结果
-o参数将服务器的回应保存成文件,等同于wget命令。
shell
代码解读
复制代码
$ curl -o example.html https://www.example.com
上面命令将www.example.com保存成example.html。
-O参数将服务器回应保存成文件,并将 URL 的最后部分当作文件名。
ruby
代码解读
复制代码
$ curl -O https://www.example.com/foo/bar.html
上面命令将服务器回应保存成文件,文件名为bar.html。
HTTP 设置Header
在curl中,我们可以使用-H或–header选项来指定Header。之前我们就使用-H指定了Content-Type,其实Header就是一个key: value对:
ruby
代码解读
复制代码
$ curl -H "HeaderName: HeaderValue" www.baidu.com
可以使用多个 -H
设置请求体内容
POST是HTTP中向服务端提交数据的一种方法。
在浏览器中,但在表单中填写完数据后,浏览器就会默认将填写的数据使用 key=value 串的形式进行转化。
在curl中,我们可以使用 -d 或 –data 选项来指定具体的数据:
bash
代码解读
复制代码
$ curl -d key1=value1&key2=value2 http://example.com
我们也可以使用多个 -d 选项来指定多组数据,curl会自动把这些数据连接起来,因此上面的例子还可以这样:
ini
代码解读
复制代码
$ curl -d key1=value1 -d key2=value2 http://example.com
当然,如果数据过多,我们还可以把数据放在一个文件中:
bash
代码解读
复制代码
$ curl -d @filename http://example.com
设置请求体内容形式 Content-Type
当使用POST方法提交数据时,对于提交的数据主要有如下四种形式:
- application/x-www-form-urlencoded:默认的形式,即key1=value1&key2=value2的形式;
- multipart/form-data:使用表单上传文件时使用这个形式;
- application/json:提交JSON格式的数据;
- text/xml:提交XML格式的数据。
Content-Type是一个Header,如果不指定的话,那么默认就是使用application/x-www-form-urlencoded形式传输数据,
当需要使用别的形式进行数据传输的话,那么就需要指定这个Header:
bash
代码解读
复制代码
$ curl -d '{I Am A JSON FORM}' -H 'Content-Type: application/json' http://example.com
提交二进制数据
在curl中,我们也可以提交一个文件,可以使用**–data-binary**选项来指定一个文件:
css
代码解读
复制代码
$ curl --data-binary @filename http://example.com
multipart form posts
如果一个HTTP POST具有如下形式的表单:
HTML
代码解读
复制代码
<form action="submit.cgi" method="post" enctype="multipart/form-data"> Name: <input type="text" name="person"><br> File: <input type="file" name="secret"><br> <input type="submit" value="Submit"> </form>
用户可以在Name中填写名字,在File中选择一个文件,然后单击Submit按钮提交数据。
为了可以在curl中模拟这个请求,我们可以使用**-F或–form**选项来指定数据:
ruby
代码解读
复制代码
$ curl -F person=annonymous -F secret=@filename http://example.com/submit.cgi
在上面的表单中,action指定了这个请求发送到哪里;method指定这是一个POST请求;而enctype指定了这是一个multipart formpost。
当执行上面的curl命令后,curl会产生如下的请求头:
makefile
代码解读
复制代码
POST /submit.cgi HTTP/1.1 Host: example.com User-Agent: curl/7.46.0 Accept: */* Content-Length: 313 Content-Type: multipart/form-data; boundary=------------------------d74496d66958873e
其中Content-Type是和enctype一致的。
当使用**-F选项时,默认的Content-Type就是multipart/form-data**,不过,我们也可以使用-H进行指定:
shell
代码解读
复制代码
$ curl -F 'name=Dan' -H 'Content-Type: multipart/magic' https://example.com
上传文件
使用curl
命令上传文件通常是通过HTTP POST请求来实现的,其中文件数据作为请求体的一部分发送。以下是一个使用curl
上传文件的示例:
arduino
代码解读
复制代码
curl -F "file=@/path/to/your/file" http://example.com/upload
这里的-F
选项用于指定表单字段,file=@/path/to/your/file
表示将名为file
的表单字段设置为指向你要上传的文件的路径。@
符号用于指示curl
读取文件内容并将其作为表单数据发送。
如果你想为上传的文件指定一个不同的字段名(不是file
),你可以这样做:
arduino
代码解读
复制代码
curl -F "fieldname=@/path/to/your/file" http://example.com/upload
将fieldname
替换为你想要的字段名。
此外,如果你的上传接口需要额外的表单字段(比如认证信息或其他元数据),你可以通过添加多个-F
选项来指定它们:
POST转换为GET
GET 请求,有的时候需要在URL后附加一些参数。在curl命令中,只能使用-d参数设置数据,而设置-d参数后,默认会把改请求设置成POST请求,-d中的参数放在请求体中。
使用**-G或-get选项,可以把一个POST请求转化成一个GET请求。如果有-d选项指定的参数,那么curl就会把-d**后面的数据添加到URL的后面,用 ? 连接。比如:
bash
代码解读
复制代码
$ curl -d "key1=value1" -G http://example.com
得到的请求URL就是:
ini
代码解读
复制代码
http://example.com/?key1=value1
URL编码
HTTP请求有的时候需要使用URL编码方式对原始的HTTP数据和参数进行编码。
HTTP请求中URL编码的使用场景主要包括以下几种情况:
- 特殊字符的传输:URL中可能包含一些特殊字符,如空格、&、#、=、%等,这些字符在URL中具有特定的含义或用途,如果直接放在URL中可能会引起解析错误或歧义。因此,这些特殊字符需要进行URL编码,以确保URL的正确解析和传输。
- 非ASCII字符的处理:URL中如果包含非ASCII字符(如中文、日文等),由于这些字符在URL中可能无法被正确识别和处理,因此也需要进行URL编码。编码后的字符以百分比形式表示,即“%”后跟两位十六进制数,这样可以确保这些字符在URL中的正确传输。
- 避免安全隐患:在某些情况下,将敏感信息直接放在URL中可能会导致安全隐患。通过对这些信息进行URL编码,可以在一定程度上增加传输过程的安全性。不过,需要注意的是,URL编码本身并不能完全保证数据的安全性,还需要结合其他安全措施一起使用。
如果使用的数据没有编码,那么可以指定curl来帮助自己进行编码。这时可以使用 –data-urlencode 选项来指定。比如:
kotlin
代码解读
复制代码
$ curl --data-urlencode "name=Alan Walker" http://example.com
HTTP请求重定向
重定向是HTTP协议中的一个基础部分。在重定向中,服务器给客户端的并不是客户端想要的内容,
而是一个车具体的指令,告诉客户端如果想获取想要的数据,应该到哪里去请求。
但不是所有的重定向都一样。重定向之后的请求使用什么方法呢?重定向多久呢?
所有的重定向都会返回Location: 的Header,来指定一个新的URL。
在curl中,默认不会重定向,可以使用-L或–location选项来告诉curl重定向:
shell
代码解读
复制代码
$ curl -L http://example.com
修改HTTP请求头的一些参数
上面提到了可以使用 -H 设置请求头的参数。这里还有一些快捷的选项
修改Referer
有些网站的网页在访问的时候需要设置跳转来源,如果跳转来源不对的话,可能会拒绝返回相应的页面。这个在爬虫和反爬虫技术中常用。
我们可以在curl通过–referer选项来指定我们是从哪里跳转过来的:
shell
代码解读
复制代码
$ curl --referer http://fromexample.com http://toexample.com
修改 User Agent
这个字段是用来表示客户端的设备信息的,服务器会根据这个字段,针对不同的设备,返回不同格式的网页。在curl中,可以使用–user-agent选的来指定:
shell
代码解读
复制代码
$ curl --user-agent "[User Agent]" http://example.com
设置cookies
HTTP是一种无状态的协议,为了在会话中保存一些状态,可以使用Cookies。服务器通过Set-Cookie:来设置Cookie,客户端就可以在下一次请求中携带这些数据。
命令行设置
我们可以使用–cookie选项来设置一个Cookie:
shell
代码解读
复制代码
$ curl --cookie "CookieName=CookieValue" http://example.com
文件中读取
curl默认不会记住服务器设置的Cookie,也不会在下一次请求中携带Cookie。除非用户通过选项自己设置。
我们可以把之前的Cookies保存到一个文件,然后在下一次请求中指定curl读取文件中的Cookies:
shell
代码解读
复制代码
$ curl -b cookies.txt http://example.com
-b选项指定curl去给定的文件中读取Cookies。
不过这里仅仅是读取Cookies,如果这次请求中服务器修改了Cookie,那么curl是不会进行保存的,除非我们手动指定。
保存Cookies
我们可以使用-c选项指定curl保存这次请求中服务器设置的Cookies:
shell
代码解读
复制代码
$ curl -c cookie.jar.txt http://example.com
有时,我们既需要从文件中读取Cookies,也需要保存服务器设置的Cookies。那么就可以同时使用-b和-c选项:
shell
代码解读
复制代码
$ curl -b cookies.txt -c cookie.jar.txt http://example.com
跳过SSL检查
我们访问一些HTTPS的站点时,浏览器或者curl都会先验证该网站的SSL证书,确保该网站是合法的。
而我们自己在开发阶段,我们自己生成的证书是没有在CA注册过的,是无法直接通过这个验证的。在使用浏览器的时候,我们可以在网页上选择信任该网站,继续访问。在curl命令中,就需要设置跳过这个检查。
-k参数指定跳过 SSL 检测。
shell
代码解读
复制代码
$ curl -k https://www.example.com
设置用户名和密码
-u参数用来设置服务器认证的用户名和密码。
ruby
代码解读
复制代码
$ curl -u 'bob:12345' https://google.com/login
上面命令设置用户名为bob,密码为12345,然后将其转为 HTTP 标头Authorization: Basic Ym9iOjEyMzQ1。
curl 能够识别 URL 里面的用户名和密码。
shell
代码解读
复制代码
$ curl https://bob:12345@google.com/login
上面命令能够识别 URL 里面的用户名和密码,将其转为上个例子里面的 HTTP 标头。
ruby
代码解读
复制代码
$ curl -u 'bob' https://google.com/login
上面命令只设置了用户名,执行后,curl 会提示用户输入密码。
设置HTTP代理
-x参数指定 HTTP 请求的代理。
perl
代码解读
复制代码
$ curl -x socks5://james:cats@myproxy.com:8080 https://www.example.com
上面命令指定 HTTP 请求通过myproxy.com:8080的 socks5 代理发出。
如果没有指定代理协议,默认为 HTTP。
java
代码解读
复制代码
$ curl -x james:cats@myproxy.com:8080 https://www.example.com
上面命令中,请求的代理使用 HTTP 协议。
循环下载
有时候下载图片可以能是前面的部分名称是一样的,就最后的尾椎名不一样
bash
代码解读
复制代码
curl -O http://www.linux.com/dodo[1-5].JPG
定制化输出
curl -w 选项用于输出 curl 命令执行后的统计信息
,可以用多种格式化字符串来获取特定的信息。会在原有的输出内容上,增加 -w 指定的内容。
bash
代码解读
复制代码
curl -w "format" [options] [url]
通常会和 -o /dev/null一起用,隐藏普通输出,仅输出-w 指定的内容
以下是一些常用的格式化选项:
shell
代码解读
复制代码
%{http_code}: HTTP 响应状态码(如 200, 404, 500 等)。 %{time_total}: 完成请求所需的总时间(单位为秒)。 %{time_namelookup}: DNS 解析所花费的时间(单位为秒)。 %{time_connect}: 建立 TCP 连接所需的时间(单位为秒)。 %{time_appconnect}: SSL/TLS 握手所需的时间(适用于 HTTPS 请求)。 %{time_pretransfer}: 从开始到准备传输所花费的时间(单位为秒)。 %{time_starttransfer}: 从开始请求到第一个字节返回所花费的时间(单位为秒)。 %{size_download}: 下载内容的字节大小。 %{size_upload}: 上传内容的字节大小。 %{speed_download}: 下载速度(单位为字节/秒)。 %{speed_upload}: 上传速度(单位为字节/秒)。 %{content_type}: 响应的内容类型(如 text/html, application/json 等)。
假设你想获取一个网页的 HTTP 响应码和请求的总时间,你可以这样做:
css
代码解读
复制代码
curl -o /dev/null -s -w "HTTP Code: %{http_code}\nTotal Time: %{time_total}\n" http://www.example.com
这条命令会输出类似以下的内容:
less
代码解读
复制代码
HTTP Code: 200 Total Time: 0.436
显示通信过程
-v, --verbose
v 参数可以显示一次 http 通信的整个过程,包括端口连接和 http request 头信息。
ruby
代码解读
复制代码
$ curl -v www.baidu.com
curl 和其他工具之间的相互转换
Chrome
在Chrome中,打开More tools->Developer模式,
选择Network选项卡,然后就可以看到所有的请求,选中相应的请求,右键就有Copy as cURL选项,单击就可以了。
Postman
在请求右边点击 Code
选择cUrl,右边就会展示转换后的内容。
大模型
直接将你要转换的代码拷贝给大模型,让他生成curl 命令。
如果是根据curl 生成代码,同样的,拷贝curl 命令,让大模型生成相应的请求代码。