文件
一個 專案

route

將一組指令逐字且作為單一單元評估。

route 區塊中包含的指令將不會被內部重新排序。只有 HTTP 處理程序指令(將處理程序或中介軟體添加到鏈的指令)才能在 route 區塊中使用。

此指令是一種特殊情況,因為其子指令也是常規指令。

語法

route [<matcher>] {
	<directives...>
}
  • <directives...> 是一個指令或指令區塊的列表,每行一個,就像在 route 區塊之外一樣; 只是這些指令不會被重新排序。 只能使用 HTTP 處理程序指令。

用途

route 指令在某些進階用例或邊緣情況下很有用,可以完全控制 HTTP 處理程序鏈的某些部分。

由於 HTTP 中介軟體評估的順序非常重要,因此 Caddyfile 通常會在解析後重新排序指令,以使 Caddyfile 更易於使用; 您不必擔心輸入的順序。

雖然內建順序與大多數網站相容,但有時您需要手動控制順序,無論是對於整個網站還是僅僅是其中一部分。 這就是 route 指令的用途。

為了說明,請考慮兩個終止處理程序的情況:redirfile_server。 兩者都將回應寫入客戶端,並且不調用鏈中的下一個處理程序,因此對於特定請求,只會執行其中一個。 那麼哪個先執行? 通常,redirfile_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_serverredir 之前執行

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
	}
}