Posted by Adam on August 24, 2022
# curl 常用指令筆記 `curl` 是用來透過終端機發送 HTTP 請求、下載內容及上傳檔案的工具。 ## 基本語法 ```bash curl [選項] URL ``` 單純取得網頁內容: ```bash curl https://example.com ``` 顯示回應標頭與內容: ```bash curl -i https://example.com ``` 只取得回應標頭: ```bash curl -I https://example.com ``` --- ## HTTP 方法 ### GET `GET` 是 curl 的預設方法,因此通常不需要加上 `-X GET`: ```bash curl http://localhost:8080/ ``` 明確指定 GET: ```bash curl -X GET http://localhost:8080/ ``` ### POST 表單資料 使用 `-d` 或 `--data` 傳送資料時,curl 會自動使用 POST: ```bash curl \ --data "email=test@example.com&press=%20OK%20" \ http://www.example.com/form.php ``` 更容易閱讀的寫法: ```bash curl \ --data-urlencode "email=test@example.com" \ --data-urlencode "press= OK " \ http://www.example.com/form.php ``` 因此通常不必額外寫: ```bash -X POST ``` ### DELETE ```bash curl -X DELETE http://localhost:8080/user/100 ``` 如果 API 需要驗證: ```bash curl -X DELETE \ -H "Authorization: Bearer YOUR_TOKEN" \ http://localhost:8080/user/100 ``` ### PUT 與 PATCH ```bash curl -X PUT \ -H "Content-Type: application/json" \ --data '{"name":"Alice"}' \ http://localhost:8080/users/100 ``` ```bash curl -X PATCH \ -H "Content-Type: application/json" \ --data '{"name":"Alice"}' \ http://localhost:8080/users/100 ``` --- ## 查詢參數與 URL 編碼 使用 `-G` 可以將 `--data-urlencode` 提供的資料放進 URL,而不是 request body: ```bash curl -G \ --data-urlencode "p1=value 1" \ --data-urlencode "p2=value 2" \ http://example.com ``` 實際請求網址相當於: ```text http://example.com?p1=value%201&p2=value%202 ``` `--data-urlencode` 適合處理空白、中文字元及 `&`、`+` 等特殊符號。 --- ## HTTP 標頭 使用 `-H` 或 `--header` 加入 request header: ```bash curl \ -H "Content-Type: application/json" \ http://www.example.com/users ``` 加入多個標頭: ```bash curl \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_TOKEN" \ http://localhost:8080/users ``` --- ## 傳送 JSON ### 直接傳送 JSON ```bash curl \ -H "Content-Type: application/json" \ --data '{"q":"apple"}' \ http://localhost:47267/sdcv/query.html ``` 新版 curl 可使用 `--json`,它會自動設定 JSON 相關標頭: ```bash curl \ --json '{"q":"apple"}' \ http://localhost:47267/sdcv/query.html ``` ### 從檔案讀取 JSON 假設資料存放在 `body.json`: ```bash curl \ -H "Content-Type: application/json" \ --data @body.json \ http://localhost:8080/ui/webapp/conf ``` 也可以寫成: ```bash curl \ --json @body.json \ http://localhost:8080/ui/webapp/conf ``` 注意:`@body.json` 中的 `@` 表示「從這個檔案讀取內容」。 --- ## 傳送純文字或原始檔案內容 如果伺服器預期 request body 是檔案的原始內容: ```bash curl -i \ -X POST \ -H "Content-Type: text/plain" \ --data-binary "@path/to/file" \ http://host:port/post-file ``` `--data-binary` 會保留檔案內容中的換行與位元組,不進行一般表單資料的轉換。 傳送二進位檔案時,可使用: ```bash curl \ -H "Content-Type: application/octet-stream" \ --data-binary "@archive.zip" \ https://example.com/upload ``` --- ## multipart/form-data 檔案上傳 若伺服器使用一般網頁表單的檔案上傳格式,請使用 `-F` 或 `--form`: ```bash curl \ --location \ --request POST \ --form 'file=@/home/adam/Downloads/archive.zip' \ --output /dev/null \ --progress-bar \ https://example.com/upload ``` 同時傳送檔案與其他欄位: ```bash curl \ --form 'file=@archive.zip' \ --form 'description=backup file' \ https://example.com/upload ``` 使用 `--form` 時,curl 會自動產生正確的 `multipart/form-data` 標頭及 boundary;不要自行固定 `Content-Type`。 --- ## 重新導向 `--location` 或 `-L` 會讓 curl 自動跟隨伺服器回傳的 HTTP 重新導向: ```bash curl --location https://example.com ``` 如果沒有使用 `-L`,curl 通常只會顯示第一次回應,不會繼續請求 `Location` 標頭指定的新網址。 縮寫: ```bash curl -L https://example.com ``` 限制最多重新導向 5 次: ```bash curl -L --max-redirs 5 https://example.com ``` 注意:重新導向到不同主機時,curl 預設不會轉送帳號密碼等敏感驗證資訊。除非完全信任目標,否則不要隨意使用 `--location-trusted`。 --- ## 查看請求與回應資訊 ### 顯示 response header ```bash curl -i https://example.com ``` ### 顯示詳細連線資訊 ```bash curl -v https://example.com ``` `-v` 會顯示 request header、response header、連線及 TLS 等資訊,適合除錯。 ```bash curl -v \ -H "Content-Type: application/json" \ https://example.com/users ``` 注意:詳細輸出可能包含 Cookie、Token 或 Authorization header,分享前應先移除敏感資訊。 ### 將 response header 與 body 分開儲存 ```bash curl \ --dump-header headers.txt \ --output body.txt \ https://example.com ``` --- ## 取得 HTTP 狀態碼 只輸出 HTTP 狀態碼: ```bash curl \ --silent \ --output /dev/null \ --write-out "%{http_code}\n" \ http://example.com:1300 ``` 縮寫版本: ```bash curl -s -o /dev/null -w "%{http_code}\n" http://example.com:1300 ``` 選項說明: - `-s`/`--silent`:不顯示進度與一般訊息。 - `-o /dev/null`:丟棄 response body。 - `-w`/`--write-out`:依指定格式輸出請求資訊。 - `%{http_code}`:HTTP 狀態碼。 - `\n`:在狀態碼後換行,方便終端機顯示。 同時顯示狀態碼與耗時: ```bash curl -s -o /dev/null \ -w "status=%{http_code} time=%{time_total}s\n" \ https://example.com ``` 注意:`curl` 預設不會因為 HTTP 404 或 500 回傳失敗的結束狀態。用於腳本時,可以加入: ```bash curl --fail-with-body https://example.com ``` --- ## 下載檔案 指定輸出檔名: ```bash curl -L \ --output archive.zip \ https://example.com/archive.zip ``` 沿用伺服器提供的檔名: ```bash curl -L -O https://example.com/archive.zip ``` 顯示簡潔的進度條: ```bash curl -L \ --progress-bar \ --output archive.zip \ https://example.com/archive.zip ``` 繼續先前中斷的下載: ```bash curl -L \ --continue-at - \ --output archive.zip \ https://example.com/archive.zip ``` --- ## Cookie 儲存伺服器回傳的 Cookie: ```bash curl \ --cookie-jar cookies.txt \ https://example.com/login ``` 讀取 Cookie 並再次請求: ```bash curl \ --cookie cookies.txt \ https://example.com/account ``` 直接指定 Cookie: ```bash curl \ --cookie "session=abc123" \ https://example.com/account ``` --- ## 驗證方式 ### Basic Authentication ```bash curl \ --user "username:password" \ https://example.com/api ``` 為避免密碼直接留在命令歷史中,可以只提供使用者名稱,讓 curl 互動式詢問密碼: ```bash curl --user "username" https://example.com/api ``` ### Bearer Token ```bash curl \ -H "Authorization: Bearer YOUR_TOKEN" \ https://example.com/api ``` --- ## 逾時與重試 設定連線逾時及整體逾時: ```bash curl \ --connect-timeout 5 \ --max-time 30 \ https://example.com ``` 失敗時最多重試 3 次: ```bash curl \ --retry 3 \ --retry-delay 2 \ https://example.com ``` --- ## 常用選項速查 | 選項 | 用途 | |---|---| | `-X METHOD` | 指定 HTTP 方法 | | `-d DATA` | 傳送資料,預設使用 POST | | `--data-binary DATA` | 原樣傳送資料或檔案內容 | | `--data-urlencode DATA` | URL encode 後傳送資料 | | `--json DATA` | 傳送 JSON 並自動設定相關標頭 | | `-G` | 將 `-d` 類資料改放到 URL query string | | `-H HEADER` | 加入 request header | | `-F NAME=VALUE` | 傳送 multipart 表單或上傳檔案 | | `-i` | 在輸出中包含 response header | | `-I` | 只取得 response header | | `-v` | 顯示詳細除錯資訊 | | `-L` | 自動跟隨重新導向 | | `-o FILE` | 將輸出寫入指定檔案 | | `-O` | 使用遠端檔名儲存 | | `-s` | 靜默執行 | | `-S` | 搭配 `-s` 時仍顯示錯誤 | | `-w FORMAT` | 輸出狀態碼、耗時等資訊 | | `-f` | HTTP 錯誤時回傳失敗狀態 | | `--fail-with-body` | HTTP 錯誤時失敗,但保留錯誤內容 | | `--progress-bar` | 顯示簡潔進度條 | | `--connect-timeout` | 設定連線逾時 | | `--max-time` | 設定整個請求的最大時間 | ## 適合腳本使用的基本組合 ```bash curl \ --silent \ --show-error \ --fail-with-body \ --location \ https://example.com/api ``` 這個組合會: - 隱藏一般進度資訊。 - 保留錯誤訊息。 - 將 HTTP 4xx、5xx 視為失敗。 - 自動跟隨重新導向。