重定向允许你重定向一个到来的请求路径到一个不同的目标路径。
重定向仅在 Node.js 环境中可用,并不影响客户端路由。
一个常见的用例是根据用户的会话数据有条件地将用户重定向到不同的页面。你可以 这样做:
import { useRouter, useSession } from "blitz"
const LoginPage: BlitzPage = () => {
const router = useRouter()
const session = useSession()
useEffect(() => {
if (session.userId) {
router.push("/home")
}
})
return /* 填充 */
}
如果你不想让客户端重定向出现“无效内容闪现”现象,你可以使用
getServerSideProps
有条件地从服务器重定向。你
可以这样做:
import { getSession } from "blitz"
export const getServerSideProps = async ({ req, res }) => {
const session = await getSession(req, res)
if (!session.userId) {
return {
redirect: {
destination: "/login",
permanent: false,
},
}
}
return { props: {} }
}
要使用全局重定向,你可以使用 blitz.config.js
中的 redirects
键:
module.exports = {
async redirects() {
return [
{
source: "/about",
destination: "/",
permanent: true,
},
]
},
}
redirects
是一个异步函数,它期望返回一个具有 source
、destination
和
permanent
属性的对象的数组:
source
是传入的请求路径模式。destination
是你想要路由到的路径。permanent
重定向是否是永久性的。basePath
:false
或 undefined
——如果为 false,匹配时将不包含
basePath,只能用于外部重写。locale
:false
或 undefined
——匹配时是否不应该包含语言环境。has
是具有 type
、key
和 value
属性的
has 对象 数组。在包含页面和 /public
文件的文件系统之前重定向将被检查。
允许路由匹配,例如 /old-blog/:slug
将匹配 /old-blog/hello-world
(无嵌
套路径):
module.exports = {
async redirects() {
return [
{
source: "/old-blog/:slug",
destination: "/news/:slug", // 匹配到的参数均可以被当做目标路径
permanent: true,
},
]
},
}
要匹配通配符路径,你可以在参数后使用 *
,例如 /blog/:slug*
将匹配
/blog/a/b/c/d/hello-world
:
module.exports = {
async redirects() {
return [
{
source: "/blog/:slug*",
destination: "/news/:slug*", // 匹配到的参数均可以被当做目标路径
permanent: true,
},
]
},
}
要匹配正则表达式路径,你可以将正则表达式括在参数后的括号中,例如
/post/:slug(\\d{1,})
将匹配 /post/123
而不是 /post/abc
:
module.exports = {
async redirects() {
return [
{
source: "/post/:slug(\\d{1,})",
destination: "/news/:slug", // 匹配到的参数均可以被当做目标路径
permanent: false,
},
]
},
}
以下字符 (
、)
、{
、}
、:
、*
、+
、?
可用于正则表达式路径匹配,
所以在 source
中使用时作为非特殊值,它们必须通过在它们之前添加 \\
来转
义:
module.exports = {
async redirects() {
return [
{
// 这将匹配欲请求的 `/english(default)/something`:
source: "/english\\(default\\)/:slug",
destination: "/en-us/:slug",
permanent: false,
},
]
},
}
要仅在 header、cookie 或查询值也匹配 has
字段时才匹配重定向并使用
。source
和所有 has
项都必须匹配才能使用重定向。
has
具有以下字段:
type
:String
——必须是 header
、cookie
、host
或 query
。key
:String
——所选类型中要匹配的键。value
:String
或 undefined
——要检查的值,如果 undefined 将匹配任意
值。像字符串这样的正则表达式可用于捕获值的特定部分,例如如果值
first-(?<paramName>.*)
用于 first-second
,那么 second
将在目的地中
使用 :paramName
。module.exports = {
async redirects() {
return [
// 如果 header 中有 `x-redirect-me` 存在,
// 将使用此重定向
{
source: "/:path*",
has: [
{
type: "header",
key: "x-redirect-me",
},
],
permanent: false,
destination: "/another-page",
},
// 如果源、查询和 cookie 匹配,
// 将使用此重定向
{
source: "/specific/:path*",
has: [
{
type: "query",
key: "page",
// 页面值在目标路径中将不可用,因为提供了值并且不适用命名的捕获组,
// 例如(?<page>home)
value: "home",
},
{
type: "cookie",
key: "authorized",
value: "true",
},
],
permanent: false,
destination: "/:path*/:page",
},
// 如果 header `x-authorized` 存在且包含一个匹配到的值,将使用此重定向
{
source: "/:path*",
has: [
{
type: "header",
key: "x-authorized",
value: "(?<authorized>yes|true)",
},
],
permanent: false,
destination: "/home?authorized=:authorized",
},
// 如果当前域名是 `example.com`,
// 当前重定向将被使用
{
source: "/:path*",
has: [
{
type: "host",
value: "example.com",
},
],
destination: "/another-page",
},
]
},
}
当利用 basePath
支持进行重定向时,每个
source
和 destination
都会自动以 basePath
为前缀,除非你向重定向添加
basePath: false
:
module.exports = {
basePath: "/docs",
async redirects() {
return [
{
source: "/with-basePath", // 自动变成 /docs/with-basePath
destination: "/another", // 自动变成 /docs/another
permanent: false,
},
{
// 自从 basePath: false 被设置后,将不添加前缀 /docs
source: "/without-basePath",
destination: "/another",
basePath: false,
permanent: false,
},
]
},
}
当利用 i18n 支持
进行重定向时,每个 source
和
destination
都会自动添加前缀来处理配置的 locales
,除非你向重定向添加
locale: false
。如果使用 locale: false
,你必须在 source
和
destination
前面加上一个区域设置,才能正确匹配。
module.exports = {
i18n: {
locales: ["en", "fr", "de"],
defaultLocale: "en",
},
async redirects() {
return [
{
source: "/with-locale", // 自动处理所有 locales
destination: "/another", // 自动传递 locales
permanent: false,
},
{
// 自从 locale: false 被设置后,将不自动处理 locales
source: "/nl/with-locale-manual",
destination: "/nl/another",
locale: false,
permanent: false,
},
{
// 自动 `en` 是 defaultLocale,将匹配 `/`
source: "/en",
destination: "/en/another",
locale: false,
permanent: false,
},
{
// 这被转换为 /(en|fr|de)/(.*) 所以不会像 /:path*
// 这样地匹配顶级 `/` 或 `/fr` 路由
source: "/(.*)",
destination: "/another",
permanent: false,
},
]
},
}
在极少数情况下,你可能需要为较旧的 HTTP 客户端分配自定义状态代码以正确重定
向。在这种情况下,你可以使用 statusCode
属性代替 permanent
属性,但不
能同时使用两者。注意:为了确保 IE11 兼容性,会自动为 308 状态码添加一个
Refresh
header。
res.redirect()
.