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) 處理區塊彼此互斥,以及 2) 處理區塊中的指令會 重新排序 為正常。 -
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
}
}