重新導向 (redirects)
重新導向功能允許您將傳入的請求路徑重新導向至不同的目標路徑。
要使用重新導向功能,您可以在 next.config.js
中使用 redirects
鍵:
redirects
是一個非同步函式,預期回傳一個包含物件的陣列,這些物件具有 source
、destination
和 permanent
屬性:
source
是傳入的請求路徑模式。destination
是您想要路由至的路徑。permanent
為true
或false
- 若為true
將使用 308 狀態碼,指示客戶端/搜尋引擎永久快取此重新導向;若為false
則使用 307 狀態碼,表示臨時性且不會被快取。
為何 Next.js 使用 307 和 308? 傳統上,302 用於臨時重新導向,301 用於永久重新導向,但許多瀏覽器會將重新導向的請求方法更改為
GET
,無論原始方法為何。例如,如果瀏覽器發送POST /v1/users
請求並收到狀態碼302
與位置/v2/users
,後續請求可能會變成GET /v2/users
而非預期的POST /v2/users
。Next.js 使用 307 臨時重新導向和 308 永久重新導向狀態碼,明確保留所使用的請求方法。
basePath
:false
或undefined
- 若為 false,則在匹配時不會包含basePath
,僅可用於外部重新導向。locale
:false
或undefined
- 是否在匹配時不包含語言環境。has
是一個包含type
、key
和value
屬性的 has 物件 陣列。missing
是一個包含type
、key
和value
屬性的 missing 物件 陣列。
重新導向會在檔案系統(包括頁面和 /public
檔案)之前進行檢查。
重新導向不會應用於客戶端路由(Link
、router.push
),除非存在 中介軟體 (Middleware) 且匹配路徑。
當應用重新導向時,請求中提供的任何查詢值都會傳遞至重新導向目標。例如,請看以下重新導向配置:
當請求 /old-blog/post-1?hello=world
時,客戶端將被重新導向至 /blog/post-1?hello=world
。
路徑匹配
允許路徑匹配,例如 /old-blog/:slug
將匹配 /old-blog/hello-world
(不包含巢狀路徑):
萬用字元路徑匹配
要匹配萬用字元路徑,您可以在參數後使用 *
,例如 /blog/:slug*
將匹配 /blog/a/b/c/d/hello-world
:
正規表示式路徑匹配
要匹配正規表示式路徑,您可以將正規表示式包裹在參數後的括號中,例如 /post/:slug(\\d{1,})
將匹配 /post/123
但不匹配 /post/abc
:
以下字元 (
、)
、{
、}
、:
、*
、+
、?
用於正規表示式路徑匹配,因此當在 source
中作為非特殊值使用時,必須在它們前面加上 \\
進行轉義:
標頭、Cookie 和查詢匹配
若要僅在標頭、Cookie 或查詢值也匹配 has
欄位或不匹配 missing
欄位時才匹配重新導向,可以使用 has
或 missing
。source
和所有 has
項目都必須匹配,且所有 missing
項目都必須不匹配,才會應用重新導向。
has
和 missing
項目可以包含以下欄位:
type
:String
- 必須是header
、cookie
、host
或query
之一。key
:String
- 要匹配的所選類型的鍵。value
:String
或undefined
- 要檢查的值,若為 undefined 則任何值都會匹配。可以使用類似正規表示式的字串來捕捉值的特定部分,例如,若值為first-(?<paramName>.*)
用於first-second
,則second
可在目標中使用:paramName
。
支援 basePath 的重新導向
當結合 basePath
支援 使用重新導向時,每個 source
和 destination
會自動加上 basePath
前綴,除非您在重新導向中新增 basePath: false
:
支援 i18n 的重新導向
當結合 i18n
支援 使用重新導向時,每個 source
和 destination
會自動加上前綴以處理配置的 locales
,除非您在重新導向中新增 locale: false
。若使用 locale: false
,您必須在 source
和 destination
前加上語言環境才能正確匹配。
在某些罕見情況下,您可能需要為舊版 HTTP 客戶端指派自訂狀態碼以正確重新導向。在這些情況下,您可以使用 statusCode
屬性而非 permanent
屬性,但不能同時使用。為了確保 IE11 相容性,會自動為 308 狀態碼新增 Refresh
標頭。
其他重新導向方式
- 在 API 路由 中,您可以使用
res.redirect()
。 - 在
getStaticProps
和getServerSideProps
中,您可以在請求時重新導向特定頁面。
版本歷史
版本 | 變更 |
---|---|
v13.3.0 | 新增 missing 。 |
v10.2.0 | 新增 has 。 |
v9.5.0 | 新增 redirects 。 |