現在隨着大量的應用轉移到網絡,做爲開發者,會常常作一些通信測試,例如從網站獲取信息、模擬用戶向網站提交或者上傳數據,查看應用通信狀況等等,如今變成了很是重要的任務。html
一塊兒來認識 cURLnginx
cURL 是一個很是有用的工具,可以進行各類 URL 操做和數據的傳輸,經過它發出網絡請求,而後獲得和提取數據,顯示在"標準輸出"(stdout)上面。ubuntu
本文只關注如何進行 HTTP 請求,若是你有對 cURL 進行更深刻了解的想法的話,可使用下面的命令:curl –help 或 curl –manual,或者參閱 cURL 的官方文檔中心[1]。api
cURL 的安裝跨域
目前主流的操做系統都已經內置了 cURL 命令,無需額外安裝。若是有須要,能夠參考如下文檔。瀏覽器
cURL 下載中心[2]緩存
Windows 安裝[3]bash
Linux 安裝[4]服務器
cURL 查看網頁源碼網絡
直接在 cURL 命令後加上網址,就能夠看到網頁源碼。咱們以網址 upyun.com 爲例(選擇該網址,主要由於它的網頁代碼較短):
mark@Mark-Li:~$ curl upyun.com
複製代碼
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>openresty/1.13.6.2</center>
</body>
</html>
複製代碼
默認 cURL 會把結果輸出到 STDOUT,可使用 -o,-o 或 重定向 將返回結果保存到文件中:
curl -o [文件名] upyun.com
curl -O [文件保存路徑] upyun.com
curl upyun.com > upyun.html
複製代碼
mark@Mark-Li:~$ curl -o upyun.html upyun.com
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 167 100 167 0 0 107 0 0:00:01 0:00:01 --:--:-- 107
mark@Mark-Li:~$ ls
upyun.html
複製代碼
HTTP 協議
HTTP 協議 用於從 WEB 服務器上讀取數據,它是基於 TCP/IP 協議上的一個簡單的協議。該協議同時也可以讓你經過使用一些不一樣的方法向服務器提交數據。
HTTP 協議是向服務器發送的要進行一個特殊操做的 ACSII 文本,隨後在要求的內容發送給客戶端以前,服務器會向客戶端發送幾行迴應的數據。
客戶端 cURL 向服務器發送一項請求,請求一般包括 方法(好比 GET、POST、HEAD 等等)、一些 請求頭、有時還有 請求正文。接到請求後,服務器返回 狀態行(代表訪回是否順利)、響應頭 和 內容正文。正文是客戶要求的數據,一般是一些 HTML 資源、圖片等等。
對 HTTP 還不夠了解?可參考 HTTP 協議講解 這篇文章。
使用 cURL 觀察 HTTP 協議
使用 cURL 的參數 -v,–verbose,會顯示出 cURL 向服務器發送的命令和其它的一些信息。–verbose 是一個很是有用的命令,尤爲是當你想調試或者瞭解 cURL 和服務器交互過程的時候。
curl –v upyun.com
複製代碼
隨後咱們就能夠觀察服務器返回的結果:
mark@Mark-Li:~$ curl -v upyun.com
* Rebuilt URL to: upyun.com/
* Trying 115.231.97.2...
* TCP_NODELAY set
* Connected to upyun.com (115.231.97.2) port 80 (#0)
> GET / HTTP/1.1
> Host: upyun.com
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 302 Moved Temporarily
< Date: Wed, 13 Mar 2019 05:28:53 GMT
< Content-Type: text/html
< Content-Length: 167
< Connection: keep-alive
< Location: https://www.upyun.com/
<
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>openresty/1.13.6.2</center>
</body>
</html>
* Connection #0 to host upyun.com left intact
複製代碼
從輸出結果咱們能夠看到,cURL 命令發起請求所使用的請求方法、請求資源、請求協議版本以及一些請求頭。服務器接收到請求後則返回狀態碼、一些響應頭以及網頁正文。
若是咱們只須要服務器的響應信息的話,可使用 -i、--include 命令。
curl –i upyun.com
mark@Mark-Li:~$ curl -i upyun.com
HTTP/1.1 302 Moved Temporarily
Date: Wed, 13 Mar 2019 05:37:57 GMT
Content-Type: text/html
Content-Length: 167
Connection: keep-alive
Location: https://www.upyun.com/
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>openresty/1.13.6.2</center>
</body>
</html>
複製代碼
若是你以爲上面的信息還不夠,那麼下面的命令能夠查看更詳細的通訊過程。curl --trace [結果輸出保存文件名] upyun.com
從上面的例子中,咱們能夠看到,當咱們請求 upyun.com 成功以後,服務器會返回一個 302 跳轉碼,並在響應頭中經過 Location 告訴訪問者應該跳轉到哪裏去。
cURL 提供了重定向跟隨的功能,經過 -L 參數就能夠響應服務器返回的跳轉指令了。
curl –L upyun.com
複製代碼
mark@Mark-Li:~$ curl -v upyun.com -Lo /dev/null
* Rebuilt URL to: upyun.com/
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 115.231.97.2...
* TCP_NODELAY set
0 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0* Connected to upyun.com (115.231.97.2) port 80 (#0)
> GET / HTTP/1.1
> Host: upyun.com
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 302 Moved Temporarily
< Date: Wed, 13 Mar 2019 06:00:50 GMT
< Content-Type: text/html
< Content-Length: 167
< Connection: keep-alive
< Location: https://www.upyun.com/
<
* Ignoring the response-body
{ [167 bytes data]
100 167 100 167 0 0 104 0 0:00:01 0:00:01 --:--:-- 104
* Connection #0 to host upyun.com left intact
* Issue another request to this URL: 'https://www.upyun.com/'
* Trying 115.231.97.2...
* TCP_NODELAY set
0 0 0 0 0 0 0 0 --:--:-- 0:00:02 --:--:-- 0* Connected to www.upyun.com (115.231.97.2) port 443 (#1)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
} [5 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [211 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [104 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [2751 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [333 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [70 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: C=CN; ST=\U6D59\U6C5F\U7701; L=\U676D\U5DDE\U5E02; O=\U676D\U5DDE\U7EAC\U97F3\U667A\U7F51\U7EDC\U6709\U9650\U516C\U53F8; OU=\U6280\U672F\U90E8; CN=*.upyun.com
* start date: Feb 15 00:00:00 2019 GMT
* expire date: Apr 15 12:00:00 2020 GMT
* subjectAltName: host "www.upyun.com" matched cert's "*.upyun.com" * issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=GeoTrust RSA CA 2018 * SSL certificate verify ok. } [5 bytes data] > GET / HTTP/1.1 > Host: www.upyun.com > User-Agent: curl/7.58.0 > Accept: */* > { [5 bytes data] < HTTP/1.1 200 OK < Content-Type: text/html; charset=utf-8 < Content-Length: 225608 < Connection: keep-alive < Vary: Accept-Encoding < Server: openresty/1.13.6.2 < Date: Wed, 13 Mar 2019 06:00:51 GMT < X-DNS-Prefetch-Control: off < X-Frame-Options: SAMEORIGIN < X-Download-Options: noopen < X-Content-Type-Options: nosniff < X-XSS-Protection: 1; mode=block < ETag: W/"37148-Mygdw8NXtImEEqWHGE0/u6E0RM8" < Vary: Accept-Encoding < X-Kong-Upstream-Latency: 152 < X-Kong-Proxy-Latency: 1 < { [15914 bytes data] 100 220k 100 220k 0 0 76841 0 0:00:02 0:00:02 --:--:-- 692k * Connection #1 to host www.upyun.com left intact 複製代碼
能夠看到 cURL 自動跳轉訪問 www.upyun.com/ 去了。
使用 cURL 向服務器發送數據
向服務器提交數據的方法有兩種:GET 和 POST 兩種方法。
GET 方式比較簡單,須要傳遞的參數直接在 URL 地址中進行傳遞便可。
例如,向百度提交搜索 curl 的任務,cURL 命令就能夠這麼發送:
curl -vo /dev/null http://www.baidu.com/s?wd=curl
複製代碼
其中 wd 就是百度服務器接收搜索關鍵字的參數名。
POST 方法必須把數據和網址分開,咱們就須要使用 -X 參數來指定請求方法,-F 參數來傳遞表單數據。
例如,我想經過又拍雲的 FROM API,向本身的存儲空間上傳一張圖片。cURL 命令就能夠這麼寫:
curl -X POST \
http://v0.api.upyun.com/iamge-blog \
-H 'Date: Wed, 13 Mar 2019 06:21:31 GMT' \
-F 'authorization=UPYUN mark:aIa6b0qwnHCffK0NxqPG0U2uBMg=' \
-F policy=eyJidWNrZXQiOiJpYW1nZS1ibG9nIiwic2F2ZS1rZXkiOiIvdGVzdF9jdXJsLmpwZyIsImV4cGlyYXRpb24iOiIxNTYwNDA2ODkyIiwiZGF0ZSI6IldlZCwgMTMgTWFyIDIwMTkgMDY6MjE6MzEgR01UIiwicmV0dXJuLXVybCI6Imh0dHBzOi8vaG9va3MudXB5dW4uY29tL1Nrd0xaN0x2TiJ9 \
-F 'file=@/home/mark/duck.jpg'
複製代碼
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying 58.222.52.249...
* TCP_NODELAY set
* Connected to v0.api.upyun.com (58.222.52.249) port 80 (#0)
> POST /iamge-blog HTTP/1.1
> Host: v0.api.upyun.com
> User-Agent: curl/7.58.0
> Accept: */*
> Date: Wed, 13 Mar 2019 06:21:31 GMT
> Content-Length: 35317
> Content-Type: multipart/form-data; boundary=------------------------a38355798f264d25
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
< HTTP/1.1 302 Moved Temporarily
< Server: marco/2.8
< Content-Type: text/html
< Connection: keep-alive
< X-Request-Id: d6046ac4c1834027d5ddba6becd020e1
< Date: Wed, 13 Mar 2019 06:34:14 GMT
< x-upyun-height: 339
< Content-Length: 157
< X-Request-Path: 403-zj-fud-209
< Location: https://hooks.upyun.com/SkwLZ7LvN?code=200&image-frames=1&file_size=34675&image-width=604&message=ok&image-type=JPEG&url=%2Ftest_curl.jpg&time=1552458854&image-height=339&mimetype=image%2Fjpeg
< x-upyun-width: 604
< Access-Control-Allow-Origin: *
< x-upyun-frames: 1
* HTTP error before end of send, stop sending
複製代碼
又拍雲的 FORM API 上傳可參閱[5]。
使用 cURL 測試代理訪問
使用 CDN 有時候會發現請求異常,爲了肯定是 CDN 平臺的故障仍是源站出現了問題,咱們就須要依次來排查。cURL 工具可使用 -x 參數來指定代理主機端口來訪問。
curl -x [protocol://]host[:port] url
複製代碼
例如,個人 CDN 加速域名爲 test.mark.com,個人源站地址爲 1.2.4.8,服務端口爲 8080,那麼就能夠經過 cURL 直接來測試源站響應。
mark@Mark-Li:~$ curl -vo /dev/null test.mark.com -x 1.2.4.8:8080
* Rebuilt URL to: test.mark.com/
* Trying 1.2.4.8...
* TCP_NODELAY set
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Connected to 1.2.4.8 (1.2.4.8) port 8080 (#0)
> GET http://test.mark.com/ HTTP/1.1
> Host: test.mark.com
> User-Agent: curl/7.58.0
> Accept: */*
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 OK
< Server: nginx/1.12.1
< Date: Wed, 13 Mar 2019 08:14:26 GMT
< Content-Type: text/html
< Content-Length: 12569
< Last-Modified: Wed, 13 Mar 2019 07:05:56 GMT
< Connection: keep-alive
< ETag: "5c88abd4-3119"
< Accept-Ranges: bytes
<
{ [12569 bytes data]
100 12569 100 12569 0 0 211k 0 --:--:-- --:--:-- --:--:-- 223k
* Connection #0 to host 1.2.4.8 left intact
複製代碼
這樣的話,咱們就繞過了 CDN 層,直接去訪問源站獲取信息了。
使用 cURL 增長或修改請求頭
有的時候須要測試網站設置的防盜鏈有無生效,例如判斷 Referer 頭、UA 標誌或須要攜帶自定義的請求頭,就能夠經過 -H 這個參數來實現。
curl -H header:value
複製代碼
例如,test.mark.com 開啓了 Referer 防盜鏈,咱們如今須要測試防盜鏈是否生效,就能夠這麼發送命令:
mark@Mark-Li:~$ curl -vo /dev/null http://test.mark.com/a/meta.jpg -H "Referer:www.baidu.com"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 183.131.200.86...
* TCP_NODELAY set
* Connected to test.mark.com (183.131.200.86) port 80 (#0)
> GET /a/meta.jpg HTTP/1.1
> Host: test.mark.com
> User-Agent: curl/7.58.0
> Accept: */*
> Referer:www.baidu.com
>
< HTTP/1.1 200 OK
< Server: marco/2.8
< Date: Wed, 13 Mar 2019 08:35:26 GMT
< Content-Type: image/jpeg
< Content-Length: 965071
< Connection: keep-alive
< X-Request-Id: e9718d0f066330f2a7c580c332492e1a; db9beca89abeb7dfd848d0cee9540dcb
< X-Source: C/200
< X-Upyun-Content-Length: 965071
< Last-Modified: Thu, 29 Nov 2018 03:13:12 GMT
< X-Upyun-Content-Type: image/jpeg
< ETag: "ec185b942ad06c895935fd75e44076f3"
< Expires: Thu, 21 Mar 2019 07:31:17 GMT
< Cache-Control: max-age=691200
< Accept-Ranges: bytes
< Age: 3849
< Via: T.81.M, V.mix-sd-dst1-082, T.75.H, M.ctn-zj-jgh1-086
<
{ [86016 bytes data]
100 942k 100 942k 0 0 2692k 0 --:--:-- --:--:-- --:--:-- 2692k
* Connection #0 to host test.mark.com left intact
複製代碼
測試跨域請求:
mark@Mark-Li:~$ curl -i http://iamge-blog.test.upcdn.net/a/meta.jpg -H "Origin:www.baidu.com"
HTTP/1.1 200 OK
Server: marco/2.8
Date: Wed, 13 Mar 2019 08:39:20 GMT
Content-Type: image/jpeg
Content-Length: 965071
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, PUT, OPTIONS, PATCH, DELETE, POST, HEAD
Access-Control-Max-Age: 86400
Access-Control-Allow-Headers: X-MARK
X-Request-Id: e9718d0f066330f2a7c580c332492e1a; fbbbd43db05fc2fb4ba3e994c5d5eec2
X-Source: U/200
X-Upyun-Content-Length: 965071
Last-Modified: Thu, 29 Nov 2018 03:13:12 GMT
X-Upyun-Content-Type: image/jpeg
ETag: "ec185b942ad06c895935fd75e44076f3"
Expires: Thu, 21 Mar 2019 07:31:17 GMT
Cache-Control: max-age=691200
Accept-Ranges: bytes
Age: 4083
Via: T.81.M, V.mix-sd-dst1-082, T.75.H, M.ctn-zj-jgh1-086
access-control-allow-credentials: true
複製代碼
以上就是 cURL 命令工具行的一些經常使用命令。
接下來咱們再來介紹一位網絡測試老大哥,dig。
優秀輔助手 DIG
Dig 是 Linux 中的域名解析工具,功能比 Windows 平臺上的nslookup 強不少,使用也很方便,Dig 是 Domain Information Groper 的縮寫,知道了來源想必你們也就容易記住這條命令了。
Dig 配置
Dig 預裝在全部 Linux 發行版和 MacOS 系統中,目前也有大神將 Dig 移植到了 Wndows 平臺。你們能夠參考這篇安裝文檔[6]來進行操做。
Dig 調用
一個典型的 dig 調用相似:
dig @server name type
複製代碼
其中:server 待查詢名稱服務器的名稱或 IP 地址,通常指定爲 DNS 服務器 name 將要查詢的資源記錄的名稱 type 顯示所需的查詢類型 - ANY、A、TXT、MX、SIG,以及任何有效查詢類型等。若是不提供任何類型參數,dig 將對記錄 A 執行查詢。
查詢 DNS 配置信息
mark@Mark-Li:~$ dig -t NS .
複製代碼
mark@Mark-Li:~$ dig www.baidu.com
複製代碼
mark@Mark-Li:~$ dig www.baidu.com @9.9.9.9
複製代碼
例如申請證書的時候,須要在域名解析的地方添加 TXT 記錄,這時候就能夠經過 dig 來查詢。
dig txt test.mark.com
複製代碼
mark@Mark-Li:~$ dig txt test.mark.com
; <<>> DiG 9.11.3-1ubuntu1.1-Ubuntu <<>> txt test.mark.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39566
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;test.mark.com. IN TXT
;; ANSWER SECTION:
test.mark.com. 1780 IN TXT "2019031100000065jk97bbbpuq25wlofojds65ldv7w186idsq00ju"
;; Query time: 1 msec
;; SERVER: 10.0.6.30#53(10.0.6.30)
;; WHEN: Wed Mar 13 17:45:03 DST 2019
;; MSG SIZE rcvd: 121
複製代碼
[1] 官方文檔中心: curl.haxx.se/docs/
[2] cURL 下載中心: curl.haxx.se/download.ht…
[3] Windows 安裝: blog.51cto.com/9410445/176…
[4] Linux 安裝: blog.csdn.net/ivan_ljf/ar…
[5] 又拍雲的 FORM API:help.upyun.com/knowledge-b…
[6] 安裝文檔: blog.51cto.com/5001660/215…
推薦閱讀: