redirects
重定向允许你将传入请求路径重定向到不同的目标路径。
¥Redirects allow you to redirect an incoming request path to a different destination path.
要使用重定向,你可以在 next.config.js
中使用 redirects
键:
¥To use redirects you can use the redirects
key in next.config.js
:
module.exports = {
async redirects() {
return [
{
source: '/about',
destination: '/',
permanent: true,
},
]
},
}
redirects
是一个异步函数,它期望返回一个包含具有 source
、destination
和 permanent
属性的对象的数组:
¥redirects
is an async function that expects an array to be returned holding objects with source
, destination
, and permanent
properties:
-
source
是传入请求路径模式。¥
source
is the incoming request path pattern. -
destination
是你要路由到的路径。¥
destination
is the path you want to route to. -
permanent
true
或false
- 如果true
将使用 308 状态代码,指示客户端/搜索引擎永久缓存重定向,如果false
将使用 307 状态代码,该状态代码是临时且不缓存的。¥
permanent
true
orfalse
- iftrue
will use the 308 status code which instructs clients/search engines to cache the redirect forever, iffalse
will use the 307 status code which is temporary and is not cached.
为什么 Next.js 使用 307 和 308?传统上 302 用于临时重定向,301 用于永久重定向,但许多浏览器将重定向的请求方法更改为
GET
,而不管原来的方法如何。例如,如果浏览器向POST /v1/users
发出请求,该请求返回位置为/v2/users
的状态代码302
,则后续请求可能是GET /v2/users
,而不是预期的POST /v2/users
。Next.js 使用 307 临时重定向和 308 永久重定向状态代码来显式保留所使用的请求方法。¥Why does Next.js use 307 and 308? Traditionally a 302 was used for a temporary redirect, and a 301 for a permanent redirect, but many browsers changed the request method of the redirect to
GET
, regardless of the original method. For example, if the browser made a request toPOST /v1/users
which returned status code302
with location/v2/users
, the subsequent request might beGET /v2/users
instead of the expectedPOST /v2/users
. Next.js uses the 307 temporary redirect, and 308 permanent redirect status codes to explicitly preserve the request method used.
-
basePath
:false
或undefined
- 如果为 false,则匹配时不会包含basePath
,只能用于外部重定向。¥
basePath
:false
orundefined
- if false thebasePath
won't be included when matching, can be used for external redirects only. -
locale
:false
或undefined
- 匹配时是否不应包含区域设置。¥
locale
:false
orundefined
- whether the locale should not be included when matching. -
has
是具有type
、key
和value
属性的 有对象 的数组。¥
has
is an array of has objects with thetype
,key
andvalue
properties. -
missing
是具有type
、key
和value
属性的 丢失对象 的数组。¥
missing
is an array of missing objects with thetype
,key
andvalue
properties.
在包含页面和 /public
文件的文件系统之前检查重定向。
¥Redirects are checked before the filesystem which includes pages and /public
files.
使用页面路由时,重定向不会应用于客户端路由(Link
、router.push
),除非 中间件 存在且与路径匹配。
¥When using the Pages Router, redirects are not applied to client-side routing (Link
, router.push
) unless Middleware is present and matches the path.
应用重定向时,请求中提供的任何查询值都将传递到重定向目标。例如,请参阅以下重定向配置:
¥When a redirect is applied, any query values provided in the request will be passed through to the redirect destination. For example, see the following redirect configuration:
{
source: '/old-blog/:path*',
destination: '/blog/:path*',
permanent: false
}
当请求 /old-blog/post-1?hello=world
时,客户端将被重定向到 /blog/post-1?hello=world
。
¥When /old-blog/post-1?hello=world
is requested, the client will be redirected to /blog/post-1?hello=world
.
路径匹配
¥Path Matching
允许路径匹配,例如 /old-blog/:slug
将匹配 /old-blog/hello-world
(无嵌套路径):
¥Path matches are allowed, for example /old-blog/:slug
will match /old-blog/hello-world
(no nested paths):
module.exports = {
async redirects() {
return [
{
source: '/old-blog/:slug',
destination: '/news/:slug', // Matched parameters can be used in the destination
permanent: true,
},
]
},
}
通配符路径匹配
¥Wildcard Path Matching
要匹配通配符路径,你可以在参数后使用 *
,例如 /blog/:slug*
将匹配 /blog/a/b/c/d/hello-world
:
¥To match a wildcard path you can use *
after a parameter, for example /blog/:slug*
will match /blog/a/b/c/d/hello-world
:
module.exports = {
async redirects() {
return [
{
source: '/blog/:slug*',
destination: '/news/:slug*', // Matched parameters can be used in the destination
permanent: true,
},
]
},
}
正则表达式路径匹配
¥Regex Path Matching
要匹配正则表达式路径,你可以将正则表达式括在参数后面的括号中,例如 /post/:slug(\\d{1,})
将匹配 /post/123
但不匹配 /post/abc
:
¥To match a regex path you can wrap the regex in parentheses after a parameter, for example /post/:slug(\\d{1,})
will match /post/123
but not /post/abc
:
module.exports = {
async redirects() {
return [
{
source: '/post/:slug(\\d{1,})',
destination: '/news/:slug', // Matched parameters can be used in the destination
permanent: false,
},
]
},
}
以下字符 (
、)
、{
、}
、:
、*
、+
、?
用于正则表达式路径匹配,因此当在 source
中用作非特殊值时,必须通过在其前面添加 \\
来转义它们:
¥The following characters (
, )
, {
, }
, :
, *
, +
, ?
are used for regex path matching, so when used in the source
as non-special values they must be escaped by adding \\
before them:
module.exports = {
async redirects() {
return [
{
// this will match `/english(default)/something` being requested
source: '/english\\(default\\)/:slug',
destination: '/en-us/:slug',
permanent: false,
},
]
},
}
标头、Cookie 和查询匹配
¥Header, Cookie, and Query Matching
仅当标头、cookie 或查询值也与 has
字段匹配或与 missing
字段不匹配时才匹配重定向。source
和所有 has
项目都必须匹配,并且所有 missing
项目不得匹配才能应用重定向。
¥To only match a redirect when header, cookie, or query values also match the has
field or don't match the missing
field can be used. Both the source
and all has
items must match and all missing
items must not match for the redirect to be applied.
has
和 missing
项目可以具有以下字段:
¥has
and missing
items can have the following fields:
-
type
:String
- 必须是header
、cookie
、host
或query
。¥
type
:String
- must be eitherheader
,cookie
,host
, orquery
. -
key
:String
- 所选类型中要匹配的键。¥
key
:String
- the key from the selected type to match against. -
value
:String
或undefined
- 要检查的值,如果未定义,则任何值都会匹配。类似正则表达式的字符串可用于捕获值的特定部分,例如 如果值first-(?<paramName>.*)
用于first-second
,则second
将可在目标中与:paramName
一起使用。¥
value
:String
orundefined
- the value to check for, if undefined any value will match. A regex like string can be used to capture a specific part of the value, e.g. if the valuefirst-(?<paramName>.*)
is used forfirst-second
thensecond
will be usable in the destination with:paramName
.
module.exports = {
async redirects() {
return [
// if the header `x-redirect-me` is present,
// this redirect will be applied
{
source: '/:path((?!another-page$).*)',
has: [
{
type: 'header',
key: 'x-redirect-me',
},
],
permanent: false,
destination: '/another-page',
},
// if the header `x-dont-redirect` is present,
// this redirect will NOT be applied
{
source: '/:path((?!another-page$).*)',
missing: [
{
type: 'header',
key: 'x-do-not-redirect',
},
],
permanent: false,
destination: '/another-page',
},
// if the source, query, and cookie are matched,
// this redirect will be applied
{
source: '/specific/:path*',
has: [
{
type: 'query',
key: 'page',
// the page value will not be available in the
// destination since value is provided and doesn't
// use a named capture group e.g. (?<page>home)
value: 'home',
},
{
type: 'cookie',
key: 'authorized',
value: 'true',
},
],
permanent: false,
destination: '/another/:path*',
},
// if the header `x-authorized` is present and
// contains a matching value, this redirect will be applied
{
source: '/',
has: [
{
type: 'header',
key: 'x-authorized',
value: '(?<authorized>yes|true)',
},
],
permanent: false,
destination: '/home?authorized=:authorized',
},
// if the host is `example.com`,
// this redirect will be applied
{
source: '/:path((?!another-page$).*)',
has: [
{
type: 'host',
value: 'example.com',
},
],
permanent: false,
destination: '/another-page',
},
]
},
}
通过 basePath 支持进行重定向
¥Redirects with basePath support
当利用 basePath
支持 进行重定向时,每个 source
和 destination
都会自动添加 basePath
前缀,除非你将 basePath: false
添加到重定向中:
¥When leveraging basePath
support with redirects each source
and destination
is automatically prefixed with the basePath
unless you add basePath: false
to the redirect:
module.exports = {
basePath: '/docs',
async redirects() {
return [
{
source: '/with-basePath', // automatically becomes /docs/with-basePath
destination: '/another', // automatically becomes /docs/another
permanent: false,
},
{
// does not add /docs since basePath: false is set
source: '/without-basePath',
destination: 'https://example.com',
basePath: false,
permanent: false,
},
]
},
}
支持 i18n 的重定向
¥Redirects with i18n support
当利用 i18n
支持 进行重定向时,每个 source
和 destination
都会自动添加前缀以处理配置的 locales
,除非你将 locale: false
添加到重定向。如果使用 locale: false
,则必须在 source
和 destination
前面加上区域设置前缀,才能正确匹配。
¥When leveraging i18n
support with redirects each source
and destination
is automatically prefixed to handle the configured locales
unless you add locale: false
to the redirect. If locale: false
is used you must prefix the source
and destination
with a locale for it to be matched correctly.
module.exports = {
i18n: {
locales: ['en', 'fr', 'de'],
defaultLocale: 'en',
},
async redirects() {
return [
{
source: '/with-locale', // automatically handles all locales
destination: '/another', // automatically passes the locale on
permanent: false,
},
{
// does not handle locales automatically since locale: false is set
source: '/nl/with-locale-manual',
destination: '/nl/another',
locale: false,
permanent: false,
},
{
// this matches '/' since `en` is the defaultLocale
source: '/en',
destination: '/en/another',
locale: false,
permanent: false,
},
// it's possible to match all locales even when locale: false is set
{
source: '/:locale/page',
destination: '/en/newpage',
permanent: false,
locale: false,
},
{
// this gets converted to /(en|fr|de)/(.*) so will not match the top-level
// `/` or `/fr` routes like /:path* would
source: '/(.*)',
destination: '/another',
permanent: false,
},
]
},
}
在极少数情况下,你可能需要为旧的 HTTP 客户端分配自定义状态代码才能正确重定向。在这些情况下,你可以使用 statusCode
属性而不是 permanent
属性,但不能同时使用两者。为了确保 IE11 兼容性,会自动为 308 状态码添加 Refresh
标头。
¥In some rare cases, you might need to assign a custom status code for older HTTP Clients to properly redirect. In these cases, you can use the statusCode
property instead of the permanent
property, but not both. To to ensure IE11 compatibility, a Refresh
header is automatically added for the 308 status code.
其他重定向
¥Other Redirects
-
在 API 路由 和 路由处理程序 内,你可以根据传入请求进行重定向。
¥Inside API Routes and Route Handlers, you can redirect based on the incoming request.
-
在
getStaticProps
和getServerSideProps
内,你可以在请求时重定向特定页面。¥Inside
getStaticProps
andgetServerSideProps
, you can redirect specific pages at request-time.
版本历史
¥Version History
版本 | 变化 |
---|---|
v13.3.0 | 添加了 missing 。 |
v10.2.0 | 添加了 has 。 |
v9.5.0 | 添加了 redirects 。 |