route
將一組指令逐字且作為單一單元評估。
route 區塊中包含的指令將不會被內部重新排序。只有 HTTP 處理程序指令(將處理程序或中介軟體添加到鏈的指令)才能在 route 區塊中使用。
此指令是一種特殊情況,因為其子指令也是常規指令。
語法
route [<matcher>] {
<directives...>
}
- <directives...> 是一個指令或指令區塊的列表,每行一個,就像在 route 區塊之外一樣; 只是這些指令不會被重新排序。 只能使用 HTTP 處理程序指令。
用途
route
指令在某些進階用例或邊緣情況下很有用,可以完全控制 HTTP 處理程序鏈的某些部分。
由於 HTTP 中介軟體評估的順序非常重要,因此 Caddyfile 通常會在解析後重新排序指令,以使 Caddyfile 更易於使用; 您不必擔心輸入的順序。
雖然內建順序與大多數網站相容,但有時您需要手動控制順序,無論是對於整個網站還是僅僅是其中一部分。 這就是 route
指令的用途。
為了說明,請考慮兩個終止處理程序的情況:redir
和 file_server
。 兩者都將回應寫入客戶端,並且不調用鏈中的下一個處理程序,因此對於特定請求,只會執行其中一個。 那麼哪個先執行? 通常,redir
在 file_server
之前執行,因為通常您只想在特定情況下發出重定向,而在一般情況下提供檔案。
但是,在某些情況下,第二個指令 (redir
) 可能具有比第二個指令 (file_server
) 更具體的匹配器。 換句話說,您想在一般情況下重定向,而僅提供特定檔案。
因此,您可能會嘗試像這樣的 Caddyfile(但這將無法按預期工作!)
example.com {
file_server /specific.html
redir https://anothersite.com{uri}
}
問題在於,在指令排序之後,redir
出現在 file_server
之前。
但在這種情況下,redir
的匹配器(隱含的 *
)是 file_server
的匹配器的超集(*
是 /specific.html
的超集)。
幸運的是,解決方案很簡單:只需將這兩個指令包裝在 route
區塊中,以確保 file_server
在 redir
之前執行
example.com {
route {
file_server /specific.html
redir https://anothersite.com{uri}
}
}
現在 file_server
將在 redir
之前鏈接,因為順序是按字面意思採取的。
類似指令
還有其他指令可以包裝 HTTP 處理程序指令,但每個指令都有其用途,具體取決於您想要表達的行為
-
handle
包裝其他指令,就像route
一樣,但有兩個區別:1) handle 區塊彼此互斥,以及 2) handle 內的指令會正常重新排序。 -
handle_path
的作用與handle
相同,但它會在運行其處理程序之前從請求中剝離前綴。 -
handle_errors
就像handle
,但僅在 Caddy 在請求處理期間遇到錯誤時才調用。
範例
將請求代理到 /api
,並根據所有其他請求是否與磁碟上的檔案匹配來重寫它們,否則重寫為 /index.html
。 然後提供該檔案。
由於 try_files
的指令順序高於 reverse_proxy
,因此它通常會被排序得更高並首先運行; 這將導致 API 請求全部被重寫為 /index.html
並且無法匹配 /api*
,因此它們都不會被代理,而是會導致 file_server
返回 404
。 將所有內容包裝在 route
中可確保 reverse_proxy
始終在請求重寫之前首先運行。
example.com {
root * /srv
route {
reverse_proxy /api* localhost:9000
try_files {path} /index.html
file_server
}
}