Skip to content

cURL 隨重定向(Follow Redirect)的一個冷知識

cURL 用途很多,若想快速做個簡單的 API 請求測試,curl 是一個方便的指令,通常會使用 -X POST 來表明 POST 請求,然後搭配 -d '{ "key": "value" }' 傳送資料,如下:

sh
curl -X POST -d '{ "key": "value" }' https://example.com/api

在大部分的情境下,這個方法都能正常運作沒有問題,直到我遇到了一種會回應 302 Found 重新導向的 API,這個方法出現問題了!

也就是說這種 API 不會直接在 response body 回應你內容,而是藉由 HTTP status code 302 來告訴你「去另一個地方取得回應的內容」。

如果是用 Postman 這類的工具就不用擔心,它會自動幫你處理請求重定向的問題,Automatically follow redirects 設定預設是啟用的 ;而 curl 指令則是需要主動加上 -L--location 來告訴 cURL 跟隨重定向取得結果,也就是:

sh
curl -L -X POST -d '{ "key": "value" }' https://example.com/api

但如果只是加入 -L 選項讓 curl 跟隨重定向,我依然得到了一個非預期的 405 Method Not Allowed 回應結果,沒理由同樣的 API 在 Postman 測試能正常運作,但在 curl 卻得到異常的回應。

最後在某個 stackoverflow comment 當中才知道一個冷知識,如果 curl 指令當中有 -d--data,請求會自動推導成 POST,也就是說 -X POST 在這種情況下是多餘的,因為 -d 本身就會使請求變成 POST。

然而在這個案例中 -X POST 遇到了 302 重新定向不僅是多餘的問題,還會造成錯誤的結果,因為 -X POST 不僅會對第一個主要請求使用 POST,連 -L 產生的第二個請求也會使用 POST,所以才導致了我會收到 405 Method Not Allowed 的回應。

sh
# 正確取得 API 回應的流程:
# POST API -> 得到 302 Found 回應 -> GET data from new location -> 得到預期的結果

# 以下指令所產生的流程為:
# POST API -> 得到 302 Found 回應
curl -X POST -d '{ "key": "value" }' https://example.com/api

# 以下指令所產生的流程為:
# POST API -> 得到 302 Found 回應 -> POST data to new location -> 得到非預期的錯誤
curl -L -X POST -d '{ "key": "value" }' https://example.com/api

# 以下指令所產生的流程為:
# POST API ->  得到 302 Found 回應 -> GET data from new location -> 得到預期的結果
curl -L -d '{ "key": "value" }' https://example.com/api

API 回應 302 重新導向並不常見,我也只在 Google AppScript 所開發的 API 請求中遇到了這個問題。 總結來說,如果打算 POST 一個請求,且請求本身有使用到 -d--data,就不要再加上 -X POST 省得多做多錯。

Written By
YI FENG XIE
YI FENG XIE

Creative Problem Solver