文件
一個 專案

route

逐字評估一組指令,並視為單一元件。

包含在 route 區塊中的指令不會在內部重新排序。只有 HTTP 處理常式指令(將處理常式或中間件新增至鏈中的指令)可用於 route 區塊中。

此指令是一個特例,因為其子指令也是一般指令。

語法

route [<matcher>] {
	<directives...>
}
  • <directives...> 是一系列指令或指令區塊,每列一個,就像在 route 區塊之外一樣;但這些指令不會重新排序。只有 HTTP 處理常式指令可用。

實用程式

route 指令在某些進階使用案例或特殊情況中很有用,可以完全控制 HTTP 處理常式鏈的部分內容。

由於 HTTP 中間件評估的順序很重要,因此 Caddyfile 通常會在剖析後重新排序指令,以簡化 Caddyfile 的使用;您不必擔心輸入順序。

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

舉例來說,考慮兩個終止處理程序的情況:redirfile_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_serverredir 之前執行即可

example.com {
	route {
		file_server /specific.html
		redir https://anothersite.com{uri}
	}
}

現在 file_server 會在 redir 之前鏈入,因為順序是逐字執行的。

類似指令

還有其他指令可以包裝 HTTP 處理程序指令,但每個指令都有其用途,具體取決於你想要傳達的行為

  • handle 會像 route 一樣包裝其他指令,但有兩個區別:1) 處理區塊彼此互斥,以及 2) 處理區塊中的指令會 重新排序 為正常。

  • handle_path 執行與 handle 相同的動作,但會在執行處理常式之前,從要求中移除字首。

  • handle_errorshandle 類似,但僅在 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
	}
}