# 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 視為失敗。
- 自動跟隨重新導向。