Tools mentioned in this article
Open the browser-based tool while you read and try the workflow immediately.
看得懂貼上的 curl,查 API 就會快很多
從文件或瀏覽器開發者工具複製來的 curl 指令,通常長這樣:
curl -X POST 'https://api.example.com/v1/items?limit=10' \
-H 'Authorization: Bearer TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"Alice","tags":["a","b"]}'
看得懂之後其實很單純,但有幾處選項組合會改變行為,不知道就會遇到「同一段指令在這裡卻不能用」。
主要選項速查表
| 選項 | 意義 |
|---|---|
-X, --request | 指定 HTTP 方法(GET / POST / PUT / DELETE) |
-H, --header | 加入請求標頭,可重複使用 |
-d, --data | 送出請求主體。加了就會變成 POST |
--data-raw | 與 -d 相同,但不把開頭的 @ 當成檔名 |
-F, --form | 以 multipart/form-data 送出(上傳檔案) |
-u, --user | 基本驗證(user:password) |
-L, --location | 追蹤重新導向(3xx) |
-o, --output | 將回應寫入檔案 |
-O, --remote-name | 以 URL 結尾的檔名儲存 |
-s, --silent | 不顯示進度 |
-S, --show-error | 搭配 -s,但仍顯示錯誤 |
-i, --include | 輸出中包含回應標頭 |
-I, --head | 送出 HEAD,只看標頭 |
-v, --verbose | 顯示完整往返內容,包含請求標頭 |
-k, --insecure | 不驗證伺服器憑證 |
--compressed | 要求壓縮傳輸 |
-b, --cookie | 送出 Cookie |
-c, --cookie-jar | 將收到的 Cookie 存成檔案 |
-w, --write-out | 結束後輸出 %{http_code} 等資訊 |
-X POST 多半可以省略
只要加上 -d,curl 就會自動變成 POST。下面兩行是一樣的:
curl -X POST https://api.example.com/items -d '{"a":1}'
curl https://api.example.com/items -d '{"a":1}'
麻煩的是反過來的情況。-X GET 搭配 -d 會產生帶有主體的 GET 請求,某些 Proxy 與伺服器會忽略或拒絕,是「本機可以、正式環境失敗」的經典原因。
另外 -d 寫多次會用 & 串起來。對表單送出很方便,對 JSON 則是災難:
# 與預期不同:送出的是 {"a":1}&{"b":2}
curl -d '{"a":1}' -d '{"b":2}' https://api.example.com/items
-d 開頭的 @ 會變成讀取檔案
當傳給 -d 的值以 @ 開頭時,curl 會讀取該檔案並送出其內容:
curl -d @payload.json https://api.example.com/items # 送出檔案內容
很方便,但把帳號或信箱原樣傳入就會出事:
# 本意:送出字串 "@alice"
# 實際:curl 去找 ./alice 這個檔案,找不到就報錯
curl -d '@alice' https://api.example.com/items
要原樣送出含 @ 的值,請用 --data-raw,它不會對 @ 做特殊處理。
Content-Type 不會自動變成 JSON
使用 -d 時,若未特別指定,curl 會送出 Content-Type: application/x-www-form-urlencoded。以為在送 JSON 卻忘了標頭,伺服器就會解析失敗:
curl -H 'Content-Type: application/json' \
-d '{"name":"Alice"}' https://api.example.com/items
curl 7.82 之後有 --json,會同時設定 Content-Type: application/json 與 Accept: application/json。但舊環境沒有這個選項,要分享的指令還是明確寫出標頭比較保險。
引號用法是最大的出錯來源
| 寫法 | 行為 |
|---|---|
'...'(單引號) | 原樣傳遞內部的 $ 與 "。送 JSON 用這個 |
"..."(雙引號) | Shell 會展開 $變數 |
JSON 本身含有雙引號,所以外層要用單引號:
# 正確
curl -d '{"name":"Alice"}' https://api.example.com/items
# Shell 會把內層引號剝掉,主體就壞了
curl -d "{"name":"Alice"}" https://api.example.com/items
若需要從環境變數帶入權杖,就刻意混用兩者:
curl -H "Authorization: Bearer $TOKEN" \
-d '{"name":"Alice"}' https://api.example.com/items
Windows 命令提示字元不會解析單引號,而 PowerShell 中的 curl 有可能是 Invoke-WebRequest 的別名。請明確呼叫 curl.exe,或改在 WSL、Git Bash 執行。
URL 含 & 時要用引號括起來
直接貼上含多個參數的 URL,Shell 會把 & 解讀成「放到背景執行」,指令就被截斷了:
# 壞掉:只送出 limit=10
curl https://api.example.com/items?limit=10&offset=20
# 正確
curl 'https://api.example.com/items?limit=10&offset=20'
含空白或非 ASCII 字元的值需要百分比編碼。可以用 URL 編碼/解碼 確認,或交給 curl 以 -G 搭配 --data-urlencode 安全地組出查詢字串:
curl -G https://api.example.com/search --data-urlencode 'q=台北 101'
兩個不該隨手加上的選項
-k / --insecure 會關閉憑證驗證。在本機測試自簽憑證時有其用途,但為了消除錯誤而加上、然後就這樣被分享或帶進正式環境,是最典型的事故。 憑證問題應該在憑證那端解決。
-L / --location 會追蹤重新導向。很方便,但 POST 被導向時,方法與主體的處理可能改變;需要固定行為時,可用 --post301、--post302、--post303 明確指定。
把讀懂的 curl 直接變成程式碼
把讀懂的 curl 搬進應用程式時,手動抄寫標頭與主體很容易出錯。貼進 cURL 轉換器,就能轉成 JavaScript、Python、Go 等語言的請求程式碼,引號對應與標頭拆解都由工具處理。
要格式化或檢查要送出的 JSON,可用 JSON 格式化工具;想看查詢字串的內容,可用 URL 參數轉 JSON。這些都在瀏覽器內完成,即使貼上含權杖的指令也不會傳送到外部。
總結
- 加了
-d就自動是 POST;-X GET搭配-d會變成不好處理的「帶主體的 GET」 -d的值以@開頭會讀取檔案,要當字串送就用--data-raw- 只用
-d是表單格式;送 JSON 要明確給標頭,或使用--json(curl 7.82+) - 送 JSON 時外層用單引號,只有需要展開變數的地方才用雙引號
- URL 含
&要用引號括住;值的編碼交給-G --data-urlencode最安全 -k不是拿來消除錯誤的工具,-L可能改變 POST 的行為
常見問題
一定要寫 -X POST 嗎?
通常不用,加上 -d 或 -F 時就會自動成為 POST。不過寫出來能表達意圖,在要分享的指令中仍有價值。該避免的是 -X GET 搭配 -d,那會變成帶主體的 GET,部分伺服器與 Proxy 會忽略或拒絕。
-d 和 --data-raw 差在哪裡?
只差在開頭 @ 的處理。-d 會把 @ 後面的字串當成檔名並送出檔案內容,--data-raw 則原樣送出字串。要送出本來就含 @ 的資料(例如電子郵件),請用 --data-raw。
我送了 JSON,伺服器卻無法解析
使用 -d 時預設的 Content-Type 是 application/x-www-form-urlencoded,所以需要加上 -H 'Content-Type: application/json'。curl 7.82 之後可用 --json 一併設定標頭。
指令在 Windows 上不能執行
命令提示字元不解析單引號,PowerShell 的 curl 也可能是 Invoke-WebRequest 的別名。請明確呼叫 curl.exe,或改用 WSL、Git Bash 等會解析單引號的 Shell。
貼上含權杖的指令安全嗎?
cURL 轉換器 完全在瀏覽器內處理,貼上的內容不會被傳送。但轉換後的程式碼仍含有權杖,建議在提交程式碼前先改成環境變數。