什么是Curl?
cURL是在命令行下工作的文件傳輸工具。
他的語法是基於URl的語法。
它支持文件上傳和下載,所以是綜合傳輸工具,但按傳統,習慣稱cURL為下載工具。
cURL還包含了用於程序開發的libcurl。
Curl支持協議
cURL支持的通信協議有:
FTP、FTPS、HTTP、HTTPS、TFTP、SFTP、Gopher、SCP、Telnet、DICT、FILE、LDAP、LDAPS、IMAP、POP3、SMTP和RTSP。
curl還支持SSL認證、HTTP POST、HTTP PUT、FTP上傳,
HTTP form based upload、proxies、HTTP/2、cookies、用戶名+密碼認證(Basic, Plain, Digest, CRAM-MD5, NTLM,
Negotiate and Kerberos)、file transfer resume、proxy tunneling。
Curl場景使用
HTTP方法
在每一個HTTP請求中,都有一個對應的方法,常用的方法有:GET、POST、HEAD和PUT。
如果在一個curl命令中不指定具體的方法,那么默認的就是使用GET方法。對於其它的方法,可以在curl命令中指定:
method | option |
---|---|
POST | -d或-F |
HEAD | -I |
PUT | -T |
Header
在curl中,使用 -i 選項可以顯示Response的Header信息,連同Body數據:
$ curl -i www.baidu.com
結果:
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Connection: Keep-Alive
Content-Length: 2381
Content-Type: text/html
Date: Mon, 17 Sep 2018 10:26:42 GMT
Etag: "588604dd-94d"
Last-Modified: Mon, 23 Jan 2017 13:27:57 GMT
Pragma: no-cache
Server: bfe/1.0.8.18
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=styleshee
t type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就
知道</title></head> <body link=#0000cc> ... </body> </html>
使用 -I 選項可以只顯示Response的Header信息:
$ curl -I www.baidu.com
POST
POST是HTTP中向服務端提交數據的一種方法。
在瀏覽器中,但在表單中填寫完數據后,瀏覽器就會默認將填寫的數據使用 key=value 串的形式進行轉化。
在curl中,我們可以使用 -d 或 –data 選項來指定具體的數據:
$ curl -d key1=value1&key2=value2 http://example.com
我們也可以使用多個 -d 選項來指定多組數據,curl會自動把這些數據連接起來,因此上面的例子還可以這樣:
$ curl -d key1=value1 -d key2=value2 http://example.com
當然,如果數據過多,我們還可以把數據放在一個文件中:
$ 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:
$ curl -d '{I Am A JSON FORM}' -H 'Content-Type: application/json' http://example.com
其中,-H就是用來指定一個具體的Header的選項,值就是key=value 的形式。當需要指定其它的Header,可以使用-H選項。
POST一個二進制數據
在curl中,我們也可以提交一個文件,可以使用–data-binary選項來指定一個文件:
$ curl --data-binary @filename http://example.com
轉化成一個GET
使用-G或-get選項,可以把一個POST請求轉化成一個GET請求。如果有-d選項指定的參數,那么curl就會把-d后面的數據添加到URL的后面,用?連接。比如:
$ curl -d "key1=value1" -G http://example.com
得到的請求URL就是:
http://example.com/?key1=value1
URL編碼
如果使用的數據沒有編碼,那么可以指定curl來幫助自己進行編碼。這時可以使用 –data-urlencode 選項來指定。比如:
$ curl --data-urlencode "name=Alan Walker" http://example.com
multipart formposts
如果一個HTTP POST具有如下形式的表單:
<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選項來指定數據:
$ curl -F person=annonymous -F secret=@filename http://example.com/submit.cgi
在上面的表單中,action指定了這個請求發送到哪里;method指定這是一個POST請求;而enctype指定了這是一個multipart formpost。
當執行上面的curl命令后,curl會產生如下的請求頭:
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進行指定:
$ curl -F 'name=Dan' -H 'Content-Type: multipart/magic' https://example.com
-d vs -F
在前面我們介紹了使用-d構造一個基本的POST請求,和-F構造一個multipart formpost請求。那么這兩個選項有啥區別以及什么時候使用呢?
這兩個選項都是把指定的數據發送到服務器上,區別在於數據傳遞的格式。大多數時候,接收端來指定希望客戶端發送數據的格式,客戶端不能隨意自己指定格式。
- HTML表單
當使用HTML表單時,會使用
標簽指定一個表單,這會讓瀏覽器使用POST方法。如果標簽中含有enctype=multipart/form-data,
這意味着使用multipart formpost方式,在curl中就是使用-F選項。一個典型的場景就是表單中含有標簽。
- 不用HTML表單
POST方法不一定非要在HTML中,在好多的service、APIs中,也可以使用POST請求。
如果這些service期望使用JSON或者其它類似的格式的數據,那么這就是一個普通的POST請求。
在curl中就可以使用-d選項。不過要注意-d的默認Content-Type是不是期望的格式,如果不是的話,可以使用-H進行更改。
HTTP重定向(redirect)
重定向是HTTP協議中的一個基礎部分。在重定向中,服務器給客戶端的並不是客戶端想要的內容,
而是一個車具體的指令,告訴客戶端如果想獲取想要的數據,應該到哪里去請求。
但不是所有的重定向都一樣。重定向之后的請求使用什么方法呢?重定向多久呢?
所有的重定向都會返回Location:的Header,來指定一個新的URL。
curl:redirect
在curl中,默認不會重定向,可以使用-L或–location選項來告訴curl重定向:
$ curl -L http://example.com
GET還是POST
第一次請求后,服務器會告訴客戶端下一次請求需要使用的方法。關於重定向的響應碼如下:
Method | Permanent | Temporary |
---|---|---|
切換到GET | 301 | 302和303 |
使用第一次請求的方法 | 308 | 307 |
我們可以指定curl在重定向時使用什么方法。
如果我們第一次請求使用的不是GET方法,重定向后也不希望curl默認使用GET方法,那么我們可以使用–post301,–post302和–post303選項來指定。
修改HTTP請求
每一個請求都有一個請求行、一些請求頭和可選的請求體,這里我們看看在curl中可以具體修改的部分,包括請求行和請求頭。
請求方法
在請求行中包含這次請求所使用的方法。我們使用下面的簡單命令就可以進行一個GET方法:
$ curl http://example.com/file
這會生成如下的請求行:
GET /file HTTP/1.1
在HTTP方法中我們可以通過具體的選項指定使用什么方法。這里我們也可以使用-X選項來進行指定:
$ curl -X POST http://example.com
修改請求頭
在curl中,我們可以使用-H或–header選項來指定Header。之前我們就使用-H指定了Content-Type,其實Header就是一個key: value對:
$ curl -H "HeaderName: HeaderValue" http://example.com
Referer
我們還可以在curl通過–referer選項來指定我們是從哪里跳轉過來的:
$ curl --referer http://fromexample.com http://toexample.com
User Agent
這個字段是用來表示客戶端的設備信息的,服務器會根據這個字段,針對不同的設備,返回不同格式的網頁。在curl中,可以使用–user-agent選的來指定:
$ curl --user-agent "[User Agent]" http://example.com
Cookies
HTTP是一種無狀態的協議,為了在會話中保存一些狀態,可以使用Cookies。服務器通過Set-Cookie:來設置Cookie,客戶端就可以在下一次請求中攜帶這些數據。
設置Cookie
我們可以使用–cookie選項來設置一個Cookie:
$ curl --cookie "CookieName=CookieValue" http://example.com
從文件中讀取Cookies
curl默認不會記住服務器設置的Cookie,也不會在下一次請求中攜帶Cookie。除非用戶通過選項自己設置。
我們可以把之前的Cookies保存到一個文件,然后在下一次請求中指定curl讀取文件中的Cookies:
$ curl -b cookies.txt http://example.com
-b選項指定curl去給定的文件中讀取Cookies。
不過要主要,這里僅僅是讀取Cookies,如果這次請求中服務器修改了Cookie,那么curl是不會進行保存的,除非我們手動指定。
寫Cookies到文件
我們可以使用-c選項指定curl保存這次請求中服務器設置的Cookies:
$ curl -c cookie.jar.txt http://example.com
有時,我們既需要從文件中讀取Cookies,也需要保存服務器設置的Cookies。那么就可以同時使用-b和-c選項:
$ curl -b cookies.txt -c cookie.jar.txt http://example.com
工具轉換
Chrome
在Chrome中,打開More tools->Developer模式,
選擇Network選項卡,然后就可以看到所有的請求,選中相應的請求,右鍵就有Copy as cURL選項,單擊就可以了。
復制出來的結果如下:
curl 'https://www.baidu.com/sugrec?prod=pc_his&from=pc_web&json=1&sid=1421_31670_32139_31253_32045_31640&hisdata=%5B%7B%22time%22%3A1576475227%2C%22kw%22%3A%22brew%22%7D%2C%7B%22time%22%3A1576481205%2C%22kw%22%3A%22perfdog%22%2C%22fq%22%3A2%7D%2C%7B%22time%22%3A1576481477%2C%22kw%22%3A%22django%E5%BA%8F%E5%88%97%E5%8C%96%E6%9F%A5%E8%AF%A2%E5%8D%95%E6%9D%A1%E6%95%B0%E6%8D%AE%22%7D%2C%7B%22time%22%3A1576487983%2C%22kw%22%3A%22%E7%88%B6%E5%AD%90%E7%BB%84%E4%BB%B6%22%7D%2C%7B%22time%22%3A1576487994%2C%22kw%22%3A%22jq%E7%88%B6%E5%AD%90%E7%BB%84%E4%BB%B6%22%7D%2C%7B%22time%22%3A1576488025%2C%22kw%22%3A%22jq%E5%AE%9E%E7%8E%B0%E7%88%B6%E5%AD%90%E7%BB%84%E4%BB%B6%22%7D%2C%7B%22time%22%3A1576488314%2C%22kw%22%3A%22require%20%E5%80%92%E5%8C%85%22%7D%2C%7B%22time%22%3A1576488328%2C%22kw%22%3A%22require%20%E5%80%92%E5%8C%85js%22%7D%2C%7B%22time%22%3A1576488745%2C%22kw%22%3A%22%E5%AE%9A%E4%BD%8D%E5%A4%A7%E6%AE%B5html%E5%B9%B6%E6%9B%B4%E6%94%B9%E5%85%B6%E4%B8%AD%E7%9A%84%E5%85%83%E7%B4%A0%22%7D%2C%7B%22time%22%3A1576509198%2C%22kw%22%3A%22mac%E4%B8%8A%E5%A5%BD%E7%94%A8%E7%9A%84%E9%9F%B3%E4%B9%90%E6%92%AD%E6%94%BE%E5%99%A8%22%7D%5D&req=2&csor=0' \
-H 'Connection: keep-alive' \
-H 'Accept: application/json, text/javascript, */*; q=0.01' \
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36' \
-H 'Sec-Fetch-Site: same-origin' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Dest: empty' \
-H 'Referer: https://www.baidu.com/' \
-H 'Accept-Language: zh-CN,zh;q=0.9' \
-H 'Cookie: BIDUPSID=CC7B33A0192F00B390F121986B2F17F4; PSTM=1576163232; BAIDUID=CC7B33A0192F00B33DCFAA82F58706DB:FG=1; BDUSS=xUVGtDSzdwQVlGT1cxcGpSUGtreVg3bGdXNnJEQW83TW16OGF6NzZKdXh3aDllSVFBQUFBJCQAAAAAAAAAAAEAAAB-tN0E6dnA6MPOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALE1-F2xNfhdN2; MCITY=-%3A; BD_UPN=123253; COOKIE_SESSION=8366_0_8_5_3_14_0_1_8_1_0_2_21552_0_1_0_1593346129_0_1593346128%7C9%237395222_271_1591328239%7C9; BD_HOME=1; delPer=0; BD_CK_SAM=1; PSINO=5; H_PS_PSSID=1421_31670_32139_31253_32045_31640; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BDRCVFR[feWj1Vr5u3D]=mk3SLVN4HKm; H_PS_645EC=9e81xM8yrPa1O7oMg2rlWLBCpc%2Fir5Ui5T3YIjWLt6FgLOUupOcgrB80vPdGV3EavmJj; WWW_ST=1593599945002; sug=3; sugstore=1; ORIGIN=0; bdime=0' \
--compressed
Fiddler
右上角 File-> Export Sessions -> Selected Sessions
選項第一個默認 cURL script -next
文件名自己定義,保存到電腦本地
login.bat 的內容可以打開,復制出來
curl -k -i --raw -o 0.dat -X POST "http://49.x.x.x:6000/api/v1/login" -H "User-Agent: Fiddler" -H "Content-Type: application/json" -H "Host: 49.x.x.x:6000"
Charles
先抓到你想要導出的接口。
如果導出的curl不能使用,先查看導出的信息。
curl -H 'Host: xxx.com' -H 'Accept: application/json' -H 'User-Agent: kwai-ios' -H 'Accept-Language: zh-Hans-CN;q=1' --compressed 'http://xxx.com'
問題出現在結尾網址,請將結尾網址提到最前面就可以了。
curl 'http://xxx.com' -H 'Host: xxx.com' -H 'Accept: application/json' -H 'User-Agent: kwai-ios' -H 'Accept-Language: zh-Hans-CN;q=1' --compressed
Postman
在請求右邊點擊 Code
選擇cUrl,右邊就會展示轉換后的內容。
Curl參數詳解
-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 'file=@photo.png' https://google.com/profile
上面命令會給 HTTP 請求加上標頭Content-Type: multipart/form-data,然后將文件photo.png作為file字段上傳。
-F參數可以指定 MIME 類型。
$ curl -F 'file=@photo.png;type=image/png' https://google.com/profile
上面命令指定 MIME 類型為image/png,否則 curl 會把 MIME 類型設為application/octet-stream。
-F參數也可以指定文件名。
$ curl -F 'file=@photo.png;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。
-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:12345@google.com/login
上面命令能夠識別 URL 里面的用戶名和密碼,將其轉為上個例子里面的 HTTP 標頭。
$ curl -u 'bob' https://google.com/login
上面命令只設置了用戶名,執行后,curl 會提示用戶輸入密碼。
-v
-v參數輸出通信的整個過程,用於調試。
$ curl -v https://www.example.com
–trace參數也可以用於調試,還會輸出原始的二進制數據。
$ curl --trace - https://www.example.com
-x
-x參數指定 HTTP 請求的代理。
$ curl -x socks5://james:cats@myproxy.com:8080 https://www.example.com
上面命令指定 HTTP 請求通過myproxy.com:8080的 socks5 代理發出。
如果沒有指定代理協議,默認為 HTTP。
$ curl -x james:cats@myproxy.com:8080 https://www.example.com
上面命令中,請求的代理使用 HTTP 協議。
-X
-X參數指定 HTTP 請求的方法。
$ curl -X POST https://www.example.com
上面命令對https://www.example.com發出 POST 請求。