概述
cURL(Client URL)是一個功能強大的命令行工具和函式庫,用於傳輸各種網路協定的資料。它支援 HTTP、HTTPS、FTP、SFTP、TELNET 等多種協定,是開發者進行 API 測試、網路除錯和自動化腳本的必備工具。
核心特徵
- 多協定支援:HTTP/HTTPS、FTP、SFTP、SMTP、POP3 等
- 豐富的選項:支援各種 HTTP 方法、標頭、認證方式
- 跨平台:適用於 Linux、macOS、Windows 等系統
- 腳本友好:輸出格式化,適合自動化處理
- 安全性:支援 SSL/TLS、各種認證機制
安全注意事項
-k / --insecure:MITM 風險
curl -k https://example.com 跳過 TLS 憑證驗證,會讓你容易受到中間人攻擊(MITM)。
僅允許使用場景:
- 本機測試自簽憑證的開發環境
- CI/CD 內部系統(確定網路是受信任的)
正確做法(而非跳過驗證):
1
2
3
4
5
| # 指定自訂 CA
curl --cacert /path/to/ca.crt https://internal-service/
# 或設定 SSL_CERT_FILE 環境變數
SSL_CERT_FILE=/path/to/ca-bundle.crt curl https://internal-service/
|
--fail-with-body(curl 7.76+)
比 --fail 更好的錯誤處理:--fail 在 HTTP 4xx/5xx 時靜默失敗,--fail-with-body 同樣在 4xx/5xx 時返回非 0 exit code,但同時顯示 response body(對排查錯誤有幫助):
1
| curl --fail-with-body https://api.example.com/data
|
HSTS 預載入
curl 本身不會強制 HSTS 預載入清單,但多數瀏覽器會。API 設計時若 endpoint 在 HSTS 清單的域名下,HTTP 請求會被瀏覽器強制升級至 HTTPS。curl 測試不代表瀏覽器行為。
基本語法
簡單範例
1
2
3
4
5
6
7
8
9
10
11
| # 基本 GET 請求
curl https://httpbin.org/get
# 查看 HTTP 響應標頭
curl -I https://google.com
# 下載檔案
curl -o filename.html https://example.com
# 靜默模式
curl -s https://api.github.com/users/octocat
|
核心選項詳解
基本操作選項
1
2
3
4
5
6
7
8
9
10
11
12
13
| # 輸出控制
-o, --output <file> # 將輸出寫入檔案
-O, --remote-name # 使用遠程檔案名稱儲存
-s, --silent # 靜默模式,不顯示進度
-S, --show-error # 顯示錯誤訊息
-v, --verbose # 詳細輸出模式
-w, --write-out <format> # 自訂輸出格式
# 基本範例
curl -o index.html https://example.com
curl -O https://example.com/file.zip
curl -s https://api.example.com/data
curl -v https://httpbin.org/get
|
HTTP 方法選項
1
2
3
4
5
6
7
8
9
10
11
| # 請求方法
-X, --request <method> # 指定 HTTP 方法
-G, --get # 強制使用 GET 方法
-I, --head # 只獲取 HTTP 標頭 (HEAD 方法)
# 範例
curl -X POST https://httpbin.org/post
curl -X PUT https://httpbin.org/put
curl -X DELETE https://httpbin.org/delete
curl -X PATCH https://httpbin.org/patch
curl -I https://httpbin.org/headers
|
資料傳送選項
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| # 資料傳送
-d, --data <data> # 發送 POST 資料
-d @filename # 從檔案讀取資料
-F, --form <name=content> # 表單資料 (multipart/form-data)
-T, --upload-file <file> # 上傳檔案
# JSON 資料範例
curl -X POST https://httpbin.org/post \
-H "Content-Type: application/json" \
-d '{"name": "John", "age": 30}'
# 表單資料範例
curl -X POST https://httpbin.org/post \
-F "name=John" \
-F "file=@upload.txt"
# 從檔案讀取資料
curl -X POST https://httpbin.org/post \
-H "Content-Type: application/json" \
-d @data.json
|
HTTP 標頭選項
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # 標頭設定
-H, --header <header> # 添加自訂標頭
-A, --user-agent <agent> # 設定 User-Agent
-e, --referer <URL> # 設定 Referer
-i, --include # 在輸出中包含響應標頭
# 範例
curl -H "Authorization: Bearer token123" https://api.example.com
curl -H "Content-Type: application/json" \
-H "Accept: application/json" \
https://api.example.com
curl -A "MyApp/1.0" https://httpbin.org/user-agent
curl -e "https://google.com" https://httpbin.org/headers
curl -i https://httpbin.org/get
|
HTTP 方法應用
GET 請求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 基本 GET 請求
curl https://jsonplaceholder.typicode.com/posts
# 帶查詢參數的 GET
curl "https://jsonplaceholder.typicode.com/posts?userId=1"
# 使用 -G 和 -d 構建查詢字串
curl -G -d "userId=1" -d "id=1" https://jsonplaceholder.typicode.com/posts
# 帶認證的 GET
curl -H "Authorization: Bearer your-token" https://api.example.com/user
# 自訂 User-Agent
curl -A "Mozilla/5.0 (Custom Agent)" https://httpbin.org/user-agent
|
POST 請求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| # JSON 資料 POST
curl -X POST https://jsonplaceholder.typicode.com/posts \
-H "Content-Type: application/json" \
-d '{
"title": "New Post",
"body": "This is the content",
"userId": 1
}'
# 表單資料 POST
curl -X POST https://httpbin.org/post \
-d "username=john" \
-d "password=secret"
# 檔案上傳 POST
curl -X POST https://httpbin.org/post \
-F "file=@document.pdf" \
-F "description=Important document"
# URL 編碼資料
curl -X POST https://httpbin.org/post \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "name=John%20Doe&email=john%40example.com"
|
PUT 和 PATCH 請求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # PUT 更新資源
curl -X PUT https://jsonplaceholder.typicode.com/posts/1 \
-H "Content-Type: application/json" \
-d '{
"id": 1,
"title": "Updated Title",
"body": "Updated content",
"userId": 1
}'
# PATCH 部分更新
curl -X PATCH https://jsonplaceholder.typicode.com/posts/1 \
-H "Content-Type: application/json" \
-d '{"title": "Partially Updated Title"}'
# 檔案替換上傳
curl -X PUT https://api.example.com/files/document.pdf \
-T document.pdf \
-H "Authorization: Bearer token"
|
DELETE 請求
1
2
3
4
5
6
7
8
9
10
11
| # 基本 DELETE
curl -X DELETE https://jsonplaceholder.typicode.com/posts/1
# 帶認證的 DELETE
curl -X DELETE https://api.example.com/users/123 \
-H "Authorization: Bearer your-token"
# 帶確認資料的 DELETE
curl -X DELETE https://api.example.com/dangerous-action \
-H "Content-Type: application/json" \
-d '{"confirm": true, "reason": "No longer needed"}'
|
認證與安全
基本認證
1
2
3
4
5
6
7
8
9
| # HTTP Basic Authentication
curl -u username:password https://httpbin.org/basic-auth/username/password
# 從提示輸入密碼
curl -u username https://httpbin.org/basic-auth/username/password
# 使用 Base64 編碼
curl -H "Authorization: Basic $(echo -n username:password | base64)" \
https://httpbin.org/basic-auth/username/password
|
Bearer Token 認證
1
2
3
4
5
6
7
8
9
| # JWT Token
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
https://api.example.com/protected
# API Key in Header
curl -H "X-API-Key: your-api-key" https://api.example.com/data
# API Key in Query
curl "https://api.example.com/data?api_key=your-api-key"
|
OAuth 2.0
1
2
3
4
5
6
7
8
9
10
| # 獲取存取令牌
curl -X POST https://oauth.example.com/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=your-client-id" \
-d "client_secret=your-client-secret"
# 使用存取令牌
curl -H "Authorization: Bearer access-token" \
https://api.example.com/protected-resource
|
SSL/TLS 選項
1
2
3
4
5
6
7
8
9
10
| # SSL 相關選項
-k, --insecure # 允許不安全的 SSL 連接
--cert <certificate> # 客戶端證書
--key <private-key> # 私鑰檔案
--cacert <CA-certificate> # CA 證書檔案
# 範例
curl -k https://self-signed.example.com
curl --cert client.crt --key client.key https://secure.example.com
curl --cacert ca-bundle.crt https://secure.example.com
|
Cookie 處理
Cookie 基本操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 發送 Cookie
curl -b "session=abc123; user=john" https://httpbin.org/cookies
# 從檔案讀取 Cookie
curl -b cookies.txt https://httpbin.org/cookies
# 儲存 Cookie 到檔案
curl -c cookies.txt https://httpbin.org/cookies/set/session/abc123
# 同時讀取和儲存 Cookie
curl -b cookies.txt -c cookies.txt https://example.com/login
# Cookie Jar 格式
curl -b cookie-jar.txt -c cookie-jar.txt https://example.com
|
會話管理
1
2
3
4
5
6
7
8
9
| # 登入並保持會話
curl -c session.txt -d "username=john&password=secret" \
https://example.com/login
# 使用會話訪問受保護頁面
curl -b session.txt https://example.com/dashboard
# 登出並清除會話
curl -b session.txt -c /dev/null https://example.com/logout
|
檔案傳輸
檔案下載
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| # 基本下載
curl -O https://example.com/file.zip
# 自訂檔案名
curl -o myfile.zip https://example.com/file.zip
# 斷點續傳
curl -C - -O https://example.com/largefile.zip
# 限制下載速度
curl --limit-rate 100k -O https://example.com/file.zip
# 下載多個檔案
curl -O https://example.com/file1.zip -O https://example.com/file2.zip
# 使用範圍下載
curl -r 0-1023 https://example.com/file.txt # 下載前 1024 位元組
|
檔案上傳
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # FTP 上傳
curl -T localfile.txt ftp://ftp.example.com/remote/
# HTTP PUT 上傳
curl -T document.pdf https://api.example.com/upload
# 表單檔案上傳
curl -F "file=@document.pdf" -F "title=My Document" \
https://example.com/upload
# 多檔案上傳
curl -F "file1=@doc1.pdf" -F "file2=@doc2.pdf" \
https://example.com/upload
# 帶進度條的上傳
curl -# -T largefile.zip https://api.example.com/upload
|
進階功能
輸出格式化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # 自訂輸出格式
curl -w "Status: %{http_code}\nTime: %{time_total}s\nSize: %{size_download} bytes\n" \
-o /dev/null -s https://example.com
# 常用格式變數
%{http_code} # HTTP 狀態碼
%{time_total} # 總耗時
%{time_connect} # 連接時間
%{time_starttransfer} # 開始傳輸時間
%{size_download} # 下載大小
%{size_upload} # 上傳大小
%{speed_download} # 下載速度
%{speed_upload} # 上傳速度
# 效能測試範例
curl -w "@curl-format.txt" -o /dev/null -s https://example.com
|
建立 curl-format.txt 檔案:
1
2
3
4
5
6
7
8
| time_namelookup: %{time_namelookup}s\n
time_connect: %{time_connect}s\n
time_appconnect: %{time_appconnect}s\n
time_pretransfer: %{time_pretransfer}s\n
time_redirect: %{time_redirect}s\n
time_starttransfer: %{time_starttransfer}s\n
----------\n
time_total: %{time_total}s\n
|
重定向處理
1
2
3
4
5
6
7
8
9
10
11
| # 跟隨重定向
curl -L https://bit.ly/shortened-url
# 限制重定向次數
curl -L --max-redirs 5 https://example.com
# 顯示重定向過程
curl -L -v https://bit.ly/shortened-url
# 不跟隨重定向(預設)
curl https://bit.ly/shortened-url
|
代理設定
1
2
3
4
5
6
7
8
9
10
11
12
13
| # HTTP 代理
curl --proxy http://proxy.example.com:8080 https://httpbin.org/ip
# SOCKS 代理
curl --socks5 localhost:1080 https://httpbin.org/ip
# 代理認證
curl --proxy-user username:password \
--proxy http://proxy.example.com:8080 \
https://httpbin.org/ip
# 排除代理
curl --noproxy localhost,127.0.0.1 https://localhost:8080/api
|
並行請求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # 背景執行
curl https://api1.example.com &
curl https://api2.example.com &
curl https://api3.example.com &
wait
# 使用 xargs 並行
echo -e "https://api1.example.com\nhttps://api2.example.com" | \
xargs -n 1 -P 2 curl -s
# 循環請求
for i in {1..5}; do
curl -s "https://api.example.com/data/$i" &
done
wait
|
API 測試實戰
REST API 測試
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| # 使用者管理 API 測試
BASE_URL="https://jsonplaceholder.typicode.com"
# 1. 獲取所有使用者
curl -s "$BASE_URL/users" | jq '.[0:3]'
# 2. 獲取特定使用者
curl -s "$BASE_URL/users/1" | jq '.'
# 3. 創建新使用者
curl -X POST "$BASE_URL/users" \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe",
"username": "johndoe",
"email": "john@example.com"
}' | jq '.'
# 4. 更新使用者
curl -X PUT "$BASE_URL/users/1" \
-H "Content-Type: application/json" \
-d '{
"id": 1,
"name": "Jane Doe",
"username": "janedoe",
"email": "jane@example.com"
}' | jq '.'
# 5. 刪除使用者
curl -X DELETE "$BASE_URL/users/1" -w "Status: %{http_code}\n"
|
API 效能測試
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| # 響應時間測試
test_api_performance() {
local url="$1"
local requests="$2"
echo "Testing $url with $requests requests..."
for i in $(seq 1 $requests); do
curl -w "%{time_total}\n" -o /dev/null -s "$url"
done | awk '{sum+=$1; count++} END {print "Average:", sum/count "s"}'
}
test_api_performance "https://httpbin.org/delay/1" 5
# 並發測試
concurrent_test() {
local url="$1"
local concurrent="$2"
local total="$3"
echo "Concurrent test: $concurrent parallel requests, $total total"
seq 1 $total | xargs -n 1 -P $concurrent -I {} \
curl -w "Request {}: %{time_total}s\n" -o /dev/null -s "$url"
}
concurrent_test "https://httpbin.org/delay/1" 3 10
|
API 健康檢查
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| #!/bin/bash
# api_health_check.sh
check_api_health() {
local name="$1"
local url="$2"
local expected_status="$3"
echo -n "Checking $name... "
response=$(curl -s -w "HTTPSTATUS:%{http_code}" "$url")
http_code=$(echo "$response" | tr -d '\n' | sed -E 's/.*HTTPSTATUS:([0-9]{3})$/\1/')
body=$(echo "$response" | sed -E 's/HTTPSTATUS:[0-9]{3}$//')
if [ "$http_code" -eq "$expected_status" ]; then
echo "✓ OK (HTTP $http_code)"
return 0
else
echo "✗ FAIL (HTTP $http_code)"
echo "Response: $body"
return 1
fi
}
# 健康檢查
check_api_health "Main API" "https://api.example.com/health" 200
check_api_health "User Service" "https://api.example.com/users/1" 200
check_api_health "Auth Service" "https://api.example.com/auth/status" 200
|
除錯與監控
詳細除錯
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 詳細模式
curl -v https://httpbin.org/get
# 追蹤 ASCII 格式
curl --trace-ascii debug.txt https://httpbin.org/get
# 追蹤二進位格式
curl --trace debug.bin https://httpbin.org/get
# 只顯示標頭
curl -I https://httpbin.org/get
# 顯示請求和響應標頭
curl -D headers.txt https://httpbin.org/get
|
網路診斷
1
2
3
4
5
6
7
8
9
10
11
12
13
| # DNS 解析時間
curl -w "DNS lookup: %{time_namelookup}s\n" -o /dev/null -s https://example.com
# 連接時間分析
curl -w "Connect: %{time_connect}s, Start transfer: %{time_starttransfer}s, Total: %{time_total}s\n" \
-o /dev/null -s https://example.com
# 檢查 SSL 證書
curl -vI https://example.com 2>&1 | grep -E "(SSL|TLS|certificate)"
# 測試不同 HTTP 版本
curl --http1.1 -I https://example.com
curl --http2 -I https://example.com
|
錯誤處理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| # 基本錯誤處理
if curl -s --fail https://api.example.com/data; then
echo "Request successful"
else
echo "Request failed with exit code $?"
fi
# 詳細錯誤資訊
curl -s -w "Status: %{http_code}, Exit: %{exitcode}\n" \
https://httpbin.org/status/404
# 重試機制
retry_curl() {
local url="$1"
local max_attempts=3
local attempt=1
while [ $attempt -le $max_attempts ]; do
echo "Attempt $attempt of $max_attempts..."
if curl -s --fail "$url"; then
echo "Success on attempt $attempt"
return 0
fi
echo "Failed attempt $attempt"
((attempt++))
sleep 2
done
echo "All attempts failed"
return 1
}
retry_curl "https://unstable-api.example.com"
|
實用腳本範例
1. API 批次測試腳本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
| #!/bin/bash
# api_batch_test.sh
API_BASE="https://jsonplaceholder.typicode.com"
AUTH_TOKEN="your-auth-token"
# 測試配置
declare -A TESTS=(
["GET /users"]="$API_BASE/users"
["GET /posts"]="$API_BASE/posts"
["GET /user/1"]="$API_BASE/users/1"
["POST /posts"]="$API_BASE/posts"
)
# 執行測試
run_tests() {
echo "Starting API batch tests..."
echo "=========================="
local passed=0
local failed=0
for test_name in "${!TESTS[@]}"; do
local url="${TESTS[$test_name]}"
echo -n "Testing $test_name... "
if [[ "$test_name" == "POST"* ]]; then
# POST 測試
response=$(curl -s -w "HTTPSTATUS:%{http_code}" \
-X POST "$url" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AUTH_TOKEN" \
-d '{"title":"Test","body":"Test content","userId":1}')
else
# GET 測試
response=$(curl -s -w "HTTPSTATUS:%{http_code}" \
-H "Authorization: Bearer $AUTH_TOKEN" \
"$url")
fi
http_code=$(echo "$response" | tr -d '\n' | sed -E 's/.*HTTPSTATUS:([0-9]{3})$/\1/')
if [[ "$http_code" -ge 200 && "$http_code" -lt 300 ]]; then
echo "✓ PASS (HTTP $http_code)"
((passed++))
else
echo "✗ FAIL (HTTP $http_code)"
((failed++))
fi
done
echo "=========================="
echo "Results: $passed passed, $failed failed"
}
run_tests
|
2. 檔案同步腳本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
| #!/bin/bash
# file_sync.sh
LOCAL_DIR="./local_files"
REMOTE_BASE="https://api.example.com/files"
AUTH_TOKEN="your-token"
sync_files() {
echo "Starting file synchronization..."
# 獲取遠程檔案列表
remote_files=$(curl -s -H "Authorization: Bearer $AUTH_TOKEN" \
"$REMOTE_BASE" | jq -r '.[].filename')
for file in $remote_files; do
local_file="$LOCAL_DIR/$file"
remote_url="$REMOTE_BASE/$file"
echo -n "Checking $file... "
if [ -f "$local_file" ]; then
# 比較檔案雜湊
local_hash=$(sha256sum "$local_file" | cut -d' ' -f1)
remote_hash=$(curl -s -I -H "Authorization: Bearer $AUTH_TOKEN" \
"$remote_url" | grep -i "x-file-hash" | cut -d' ' -f2 | tr -d '\r')
if [ "$local_hash" = "$remote_hash" ]; then
echo "✓ Up to date"
continue
fi
fi
# 下載檔案
echo "⬇ Downloading..."
curl -s -H "Authorization: Bearer $AUTH_TOKEN" \
-o "$local_file" "$remote_url"
if [ $? -eq 0 ]; then
echo "✓ Downloaded successfully"
else
echo "✗ Download failed"
fi
done
}
mkdir -p "$LOCAL_DIR"
sync_files
|
3. 網站監控腳本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
| #!/bin/bash
# website_monitor.sh
SITES=(
"https://example.com"
"https://api.example.com/health"
"https://cdn.example.com"
)
TIMEOUT=10
LOG_FILE="/var/log/website_monitor.log"
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
check_site() {
local url="$1"
local name=$(echo "$url" | sed 's|https\?://||' | sed 's|/.*||')
response=$(curl -s -w "HTTPSTATUS:%{http_code};TIME:%{time_total}" \
--max-time "$TIMEOUT" "$url")
if [ $? -eq 0 ]; then
http_code=$(echo "$response" | grep -o "HTTPSTATUS:[0-9]*" | cut -d: -f2)
time_total=$(echo "$response" | grep -o "TIME:[0-9.]*" | cut -d: -f2)
if [ "$http_code" = "200" ]; then
log_message "✓ $name - OK (${time_total}s)"
else
log_message "⚠ $name - HTTP $http_code (${time_total}s)"
fi
else
log_message "✗ $name - TIMEOUT or ERROR"
fi
}
log_message "Starting website monitoring..."
for site in "${SITES[@]}"; do
check_site "$site"
done
log_message "Monitoring completed"
|
效能最佳化
連接重用
1
2
3
4
5
6
7
8
9
10
| # HTTP/1.1 Keep-Alive
curl --keepalive-time 30 https://api.example.com/endpoint1
curl --keepalive-time 30 https://api.example.com/endpoint2
# HTTP/2 多路復用
curl --http2 https://example.com/resource1
curl --http2 https://example.com/resource2
# 連接池配置
curl --max-time 30 --connect-timeout 10 https://api.example.com
|
快取與壓縮
1
2
3
4
5
6
7
8
9
10
| # 啟用壓縮
curl -H "Accept-Encoding: gzip, deflate" https://example.com
# 條件請求
curl -H "If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT" \
https://example.com/data
# ETag 支援
curl -H "If-None-Match: \"33a64df551425fcc55e4d42a148795d9f25f89d4\"" \
https://example.com/resource
|
批次優化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # 並行下載
urls=(
"https://api.example.com/data1"
"https://api.example.com/data2"
"https://api.example.com/data3"
)
for url in "${urls[@]}"; do
curl -s "$url" > "$(basename "$url").json" &
done
wait
# 限制並行數
printf "%s\n" "${urls[@]}" | xargs -n 1 -P 3 -I {} \
sh -c 'curl -s "{}" > "$(basename "{}").json"'
|
常見問題與解決方案
SSL/TLS 問題
1
2
3
4
5
6
7
8
9
| # 證書驗證問題
curl -k https://self-signed.example.com # 跳過驗證(不推薦)
curl --cacert /path/to/ca-bundle.crt https://example.com # 指定 CA
# 檢查證書資訊
curl -vI https://example.com 2>&1 | grep -A 10 "Server certificate"
# 測試 SSL 配置
curl --tlsv1.2 --ciphers HIGH https://example.com
|
編碼問題
1
2
3
4
5
6
7
8
| # UTF-8 編碼
curl -H "Accept-Charset: utf-8" https://example.com
# URL 編碼
curl "https://example.com/search?q=$(echo '中文查詢' | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- | cut -c3-)"
# 處理特殊字元
curl -G -d "query=hello world" https://example.com/search
|
超時與重試
1
2
3
4
5
6
7
8
9
| # 超時設定
curl --connect-timeout 10 --max-time 30 https://slow-api.example.com
# 自動重試
curl --retry 3 --retry-delay 5 https://unstable-api.example.com
# 指數退避
curl --retry 3 --retry-delay 1 --retry-max-time 60 \
https://api.example.com
|
總結
核心優勢
- 多功能性:支援多種協定和操作方式
- 靈活性:豐富的選項和配置能力
- 可程式性:適合自動化和腳本處理
- 跨平台:在各種系統上表現一致
- 效能:高效的網路通訊和傳輸
最佳實踐
- 安全第一:正確處理認證和 SSL 驗證
- 錯誤處理:實作適當的重試和錯誤恢復機制
- 效能優化:使用連接重用和並行處理
- 日誌記錄:保留詳細的請求和響應日誌
- 測試自動化:將 API 測試整合到 CI/CD 流程
常用模式記憶
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # API 測試基本模式
curl -X POST https://api.example.com/resource \
-H "Content-Type: application/json" \
-H "Authorization: Bearer token" \
-d '{"key": "value"}'
# 檔案操作模式
curl -O https://example.com/file.zip # 下載
curl -T file.txt https://api.example.com/upload # 上傳
# 除錯模式
curl -v -I https://example.com # 詳細標頭
curl -w "%{http_code}\n" https://example.com # 狀態碼
# 效能測試模式
curl -w "@curl-format.txt" -o /dev/null -s https://example.com
|
cURL 是現代開發者工具箱中不可或缺的利器,掌握其核心功能和進階技巧,能夠大幅提升 API 開發、測試和維護的效率。記住:實務中最重要的是理解 HTTP 協定基礎,並善用 cURL 的豐富選項來解決實際問題。
參考資料
留言討論