curl是一个命令行工具,通过指定的URL来上传或下载数据,并将数据展示出来。curl中的c
表示client,而URL,就是URL。这里我们介绍一下curl的使用。
1. 命令行基础
1.1 命令行选项
1. 短形式
在curl中可以使用短形式的命令行选项,比如通知curl打开verbose模式,可以使用-v
选项:
1 | curl -v www.baidu.com |
这里,-v
就是短形式的选项,我们使用一个中划线(-)并紧跟着一个字母来指定一个短形式的选项。
在这个例子中,-v
就像一个开关一样,指定某个变量是false
还是true
。我们可以在一个中划线后面跟多个单字母的选项:
1 | curl -vL www.baidu.com |
在curl中,命令行解析器总是解析整个命令行,因此,选项可以放在整个命令行的任何位置:
1 | curl www.baidu.com -vL |
这个和上面的命令具有同样的效果。当然,虽然是任何位置,但不能放在curl
前面啊:
1 | -vL curl www.baidu.com // No command '-vL' found |
2. 长形式
单个字母的选项敲起来和用起来都很方便,但是字母的个数有限而需要控制的东西又太多,这个时候就可以使用选项的长形式。同样,为了使得命令便于阅读,绝大多数短形式都有一个对应的长形式。
和短形式不同的是,长形式的选项使用两个中划线(–)指定,然后紧跟着具体的选项。还有就是,在使用长形式的时候,—
后面只能跟一个选项。对于-v
,对应的长形式如下:
1 | curl --verbose www.baidu.com |
同样,长形式的选项也可以出现在命令的任何地方:
1 | curl www.baidu.com --verbose |
对于-vL
来说,对应的长形式可以是:
1 | curl --verbose --location www.baidu.com |
或者:
1 | curl --location www.baidu.com --verbose |
3. 选项的参数
在上面的命令中选项-v
(或--verbose
)以及-L
(或--location
)都是bool
类型的标志位,来告诉curl打开或关闭某些特征。curl还有一种类型的选项,就是需要传递一些参数。比如,如果想在一个HTTP POST中向服务器传递一个字符串:
1 | curl -d arbitrary http://example.com |
同样,也可以使用相应的长形式:
1 | curl --data arbitrary http://example.com |
4. 参数有空格?
在上面的例子中,我们的参数arbitrary
是一个连续的字符串,但是当我们需要传递一个有空格的参数怎么办?比如Are you OK?
,这时我们需要使用引号把参数括起来:
1 | curl -A "Are you OK?" http://example.com |
如果不加引号的话:
1 | curl -A Are you OK? http://example.com |
那么curl只会把Are
当做用户的参数,剩下的字符,you
和OK?
会被curl当做额外的URL处理,因为这里并没有用-
指定这是一个选项。
但是如果参数本身有引号的时候怎么办?这在使用JSON传递参数的时候尤其常见,我们可以使用单引号把参数括起来(不过在Windows中不管用):
1 | curl -d '{"name":"fool"}' http://example.com |
当数据很多时,我们可以指定一个文件,来传递给curl:
1 | curl -d @params.json http://example.com |
5. Say No
对于像-t
和-L
之类的标志选项,我们可以在长形式的前面加上no-
前缀来指定关闭相应的特征,比如关闭verbose
模式:
1 | curl --no-verbose http://example.com |
1.2 URL
curl支持在一个命令行中处理多个URL,中间用空格间隔即可。curl会对传进来的URL做简单的验证,而不会去验证URL是否真正有效,因此,这里需要使用者提供有效的URL。
前面说过,curl首先解析整个命令行,将得到选项应用于所有的URL上。如果想对每一个URL使用不同的选项,那么可以使用--next
来指定。比如:
1 | curl --location http://example.com/1 |
1. 配置文件
如果选项过多,导致命令很难输入,或者超过了系统命令最大长度的限制,我们可以使用配置文件(config file)来指定curl的选项。
通过使用-K
或--config
选项来告诉curl从指定的文件中读取选项,比如:
1 | curl -K curl.options http://example.com |
在文件curl.options
中,列出所有需要的选项:
1 | ask curl to follow redirects |
和在命令行中一样,在配置文件中也可以使用长形式或短形式,甚至在配置文件中对于长形式可以省略那两个中划线(–):
1 | ask curl to follow redirects |
对于使用参数的选项,同样可以使用配置文件:
1 | ask curl to change the User-Agent in HTTP header |
既然叫做配置文件,那么上面的选项也可以写作:
1 | ask curl to change the User-Agent in HTTP header |
甚至可以省略没有空格的参数的引号:
1 | ask curl to change the User-Agent in HTTP header |
当然,如果参数中有空格的话就不能省略引号了。
2. 开始使用curl
在前面我们简单地介绍了什么是curl以及一些基础的命令行知识。我们通过命令行的方式将需要处理的URL交给curl去处理。
在这里,我们开始着手使用curl,了解curl能做什么以及如何去做。
2.1 Verbose模式
如果curl得到的结果不是期望的结果,我们可以使用-v
或--verbose
进入Verbose模式获取更多的信息。
1. 查看通信过程
在Verbose模式中,curl会得到更多的对话式信息,帮助我们了解发生了什么。curl会在每一个信息前面加上*进行标识。在下面的例子中,我们将百度的首页保存下来(使用-o
选项并指定参数baidu
):
1 | curl -v www.baidu.com -o baidu |
我们可以得到如下的信息:
1 | * About to connect() to www.baidu.com port 80 (#0) |
下面的信息是建立一个链接:
1 | * About to connect() to www.baidu.com port 80 (#0) |
然后就是本次的HTTP请求:
1 | GET / HTTP/1.1 |
接下来是数据的传输过程。然后就是响应:
1 | < HTTP/1.1 200 OK |
连箭头都不一样了。
2. 更详细的信息
如果觉得使用-v
的信息还不够的话,还可以使用--trace [filename]
选项来讲完整的流保存到filename
中。比如:
1 | curl --trace dump www.baidu.com |
之后,就可以发现一个新的文件dump
,里面保存着刚才那个会话的所有信息:
1 | == Info: About to connect() to www.baidu.com port 80 (#0) |
文件的前21行如上所示。每一个发送和接收的数据以十六进制的形式保存起来了,方便以后的分析。
如果觉得十六进制没啥帮助的话,可以使用--trace-ascii [filename]
选项:
1 | curl --trace-ascii dump www.baidu.com |
结果如下:
1 | == Info: About to connect() to www.baidu.com port 80 (#0) |
上面就是前21行的输出。
3. Silence
verbose模式的对立模式,就是silence,可以使用-s
或--silence
选项来告诉curl不输出任何程序的信息或者错误信息,但也会输出响应的结果。
如果需要在有错误的时候输出错误信息,可以使用-S
或--show-error
来指定。
2.2 浏览器到curl
别人使用浏览器发起了一个请求之后,如果自己想用curl再来一次同样的请求,这里日常的工作中是比较常见的一个操作。在curl中,有没有什么比较简便快捷的方式来获得curl命令呢?
Chrome浏览器和Firefox浏览器都实现了复制成curl的工具,可以将浏览器的请求快速复制成curl命令,非常方便快捷。
1. Chrome
在Chrome中,打开More tools->Developer模式,选择Network选项卡,然后就可以看到所有的请求,选中相应的请求,右键就有Copy as cURL
选项,单击就可以了。
2. Firefox
在Firefox中,打开Web Developer->Network工具,然后右键想要复制的链接,就有一个Copy as cURL
的选项,单击就可以了。
3. HTTP与curl
与curl一起使用的协议,最多的还是HTTP,这里就将介绍如何有效地使用curl来发送HTTP请求。
3.1 HTTP方法
在每一个HTTP请求中,都有一个对应的方法,常用的方法有:GET
、POST
、HEAD
和PUT
。
如果在一个curl命令中不指定具体的方法,那么默认的就是使用GET
方法。对于其它的方法,可以在curl命令中指定:
method | option |
---|---|
`POST` | `-d`或`-F` |
`HEAD` | `-I` |
`PUT` | `-T` |
3.2 Header
在curl中,使用-i
选项可以显示Response的Header信息,连同Body数据:
1 | curl -i www.baidu.com |
结果:
1 | HTTP/1.1 200 OK |
使用-I
选项可以只显示Response的Header信息:
1 | curl -I www.baidu.com |
3.3 POST
POST
是HTTP中向服务端提交数据的一种方法。在浏览器中,但在表单中填写完数据后,浏览器就会默认将填写的数据使用key=value
串的形式进行转化。在curl中,我们可以使用-d
或--data
选项来指定具体的数据:
1 | curl -d key1=value1&key2=value2 http://example.com |
我们也可以使用多个-d
选项来指定多组数据,curl会自动把这些数据连接起来,因此上面的例子还可以这样:
1 | curl -d key1=value1 -d key2=value2 http://example.com |
当然,如果数据过多,我们还可以把数据放在一个文件中:
1 | curl -d @filename http://example.com |
1. 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:
1 | curl -d '{I Am A JSON FORM}' -H 'Content-Type: application/json' http://example.com |
其中,-H
就是用来指定一个具体的Header的选项,值就是key=value
的形式。当需要指定其它的Header,可以使用-H
选项。
2. POST一个二进制数据
在curl中,我们也可以提交一个文件,可以使用--data-binary
选项来指定一个文件:
1 | curl --data-binary @filename http://example.com |
3. 转化成一个GET
使用-G
或-get
选项,可以把一个POST请求转化成一个GET请求。如果有-d
选项指定的参数,那么curl就会把-d
后面的数据添加到URL的后面,用?
连接。比如:
1 | curl -d "key1=value1" -G http://example.com |
得到的请求URL就是:
1 | http://example.com/?key1=value1 |
4. URL编码
如果使用的数据没有编码,那么可以指定curl来帮助自己进行编码。这时可以使用--data-urlencode
选项来指定。比如:
1 | curl --data-urlencode "name=Alan Walker" http://example.com |
5. multipart formposts
如果一个HTTP POST具有如下形式的表单:
1 | <form action="submit.cgi" method="post" enctype="multipart/form-data"> |
用户可以在Name
中填写名字,在File
中选择一个文件,然后单击Submit
按钮提交数据。
为了可以在curl中模拟这个请求,我们可以使用-F
或--form
选项来指定数据:
1 | curl -F person=annonymous -F secret=@filename http://example.com/submit.cgi |
在上面的表单中,action
指定了这个请求发送到哪里;method
指定这是一个POST
请求;而enctype
指定了这是一个multipart formpost。
当执行上面的curl命令后,curl会产生如下的请求头:
1 | POST /submit.cgi HTTP/1.1 |
其中Content-Type
是和enctype
一致的。
当使用-F
选项时,默认的Content-Type
就是multipart/form-data
,不过,我们也可以使用-H
进行指定:
1 | curl -F 'name=Dan' -H 'Content-Type: multipart/magic' https://example.com |
6. -d
vs -F
在前面我们介绍了使用-d
构造一个基本的POST请求,和-F
构造一个multipart formpost请求。那么这两个选项有啥区别以及什么时候使用呢?
这两个选项都是把指定的数据发送到服务器上,区别在于数据传递的格式。大多数时候,接收端来指定希望客户端发送数据的格式,客户端不能随意自己指定格式。
- HTML表单
当使用HTML表单时,会使用<form>
标签指定一个表单,这会让浏览器使用POST
方法。如果标签中含有enctype=multipart/form-data
,这意味着使用multipart formpost方式,在curl中就是使用-F
选项。一个典型的场景就是表单中含有<input type=file>
标签。
- 不用HTML表单
POST
方法不一定非要在HTML中,在好多的service、APIs中,也可以使用POST
请求。
如果这些service期望使用JSON或者其它类似的格式的数据,那么这就是一个普通的POST请求。在curl中就可以使用-d
选项。不过要注意-d
的默认Content-Type是不是期望的格式,如果不是的话,可以使用-H
进行更改。
3.4 HTTP重定向(redirect)
重定向是HTTP协议中的一个基础部分。在重定向中,服务器给客户端的并不是客户端想要的内容,而是一个车具体的指令,告诉客户端如果想获取想要的数据,应该到哪里去请求。
但不是所有的重定向都一样。重定向之后的请求使用什么方法呢?重定向多久呢?
所有的重定向都会返回Location:
的Header,来指定一个新的URL。
1. curl:redirect
在curl中,默认不会重定向,可以使用-L
或--location
选项来告诉curl重定向:
1 | curl -L http://example.com |
2. GET
还是POST
第一次请求后,服务器会告诉客户端下一次请求需要使用的方法。关于重定向的响应码如下:
Method | Permanent | Temporary |
---|---|---|
切换到`GET` | 301 | 302和303 |
使用第一次请求的方法 | 308 | 307 |
3.5 修改HTTP请求
每一个请求都有一个请求行、一些请求头和可选的请求体,这里我们看看在curl中可以具体修改的部分,包括请求行和请求头。
1. 请求方法
在请求行中包含这次请求所使用的方法。我们使用下面的简单命令就可以进行一个GET
方法:
1 | curl http://example.com/file |
这会生成如下的请求行:
1 | GET /file HTTP/1.1 |
在HTTP方法中我们可以通过具体的选项指定使用什么方法。这里我们也可以使用-X
选项来进行指定:
1 | curl -X POST http://example.com |
2. 修改请求头
在curl中,我们可以使用-H
或--header
选项来指定Header。之前我们就使用-H
指定了Content-Type
,其实Header就是一个key: value
对:
1 | curl -H "HeaderName: HeaderValue" http://example.com |
3. Referer
我们还可以在curl通过--referer
选项来指定我们是从哪里跳转过来的:
1 | curl --referer http://fromexample.com http://toexample.com |
4. User Agent
这个字段是用来表示客户端的设备信息的,服务器会根据这个字段,针对不同的设备,返回不同格式的网页。在curl中,可以使用--user-agent
选的来指定:
1 | curl --user-agent "[User Agent]" http://example.com |
3.6 Cookies
HTTP是一种无状态的协议,为了在会话中保存一些状态,可以使用Cookies。服务器通过Set-Cookie:
来设置Cookie,客户端就可以在下一次请求中携带这些数据。
1. 设置Cookie
我们可以使用--cookie
选项来设置一个Cookie:
1 | curl --cookie "CookieName=CookieValue" http://example.com |
2. 从文件中读取Cookies
curl默认不会记住服务器设置的Cookie,也不会在下一次请求中携带Cookie。除非用户通过选项自己设置。
我们可以把之前的Cookies保存到一个文件,然后在下一次请求中指定curl读取文件中的Cookies:
1 | curl -b cookies.txt http://example.com |
-b
选项指定curl去给定的文件中读取Cookies。
不过要主要,这里仅仅是读取Cookies,如果这次请求中服务器修改了Cookie,那么curl是不会进行保存的,除非我们手动指定。
3. 写Cookies到文件
我们可以使用-c
选项指定curl保存这次请求中服务器设置的Cookies:
1 | curl -c cookie.jar.txt http://example.com |
有时,我们既需要从文件中读取Cookies,也需要保存服务器设置的Cookies。那么就可以同时使用-b
和-c
选项:
1 | curl -b cookies.txt -c cookie.jar.txt http://example.com |
作者:今天中午吃啥
链接:https://www.jianshu.com/p/fc0eb6c60816
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。