redirect 函数允许您将用户重定向到另一个 URL。redirect 可以在渲染 服务器组件和客户端组件、路由处理器 和 服务器操作 时使用。
当在 流式上下文 中使用时,这会插入一个 meta 标签以在客户端发出重定向。当在服务器操作中使用时,它将向调用者提供一个 303 HTTP 重定向响应。否则,它将向调用者提供一个 307 HTTP 重定向响应。
如果资源不存在,您可以使用 notFound 函数 代替。
redirect 函数接受两个参数:
redirect(path, type)| 参数 | 类型 | 描述 |
|---|---|---|
path | string | 要重定向到的 URL。可以是相对路径或绝对路径。 |
type | 'replace' (默认) 或 'push' (服务器操作中默认) | 要执行的重定向类型。 |
默认情况下,redirect 在 服务器操作 中使用 push(向浏览器历史栈添加新条目),在其他所有地方使用 replace(替换浏览器历史栈中的当前 URL)。您可以通过指定 type 参数来覆盖此行为。
RedirectType 对象包含 type 参数的可用选项。
import { redirect, RedirectType } from 'next/navigation'
redirect('/redirect-to', RedirectType.replace)
// or
redirect('/redirect-to', RedirectType.push)在服务器组件中使用时,type 参数没有效果。
redirect 不返回任何值。
try/catch 语句时,redirect 应该在 try 块外部调用。permanentRedirect 函数 代替。redirect 会抛出错误,因此当使用 try/catch 语句时,它应该在 try 块外部调用。redirect 可以在客户端组件的渲染过程中调用,但不能在事件处理器中调用。您可以使用 useRouter 钩子 代替。redirect 也接受绝对 URL,可用于重定向到外部链接。next.config.js 或 Proxy。调用 redirect() 函数会抛出 NEXT_REDIRECT 错误,并终止其所在的路由片段的渲染。
import { redirect } from 'next/navigation'
async function fetchTeam(id: string) {
const res = await fetch('https://...')
if (!res.ok) return undefined
return res.json()
}
export default async function Profile({
params,
}: {
params: Promise<{ id: string }>
}) {
const { id } = await params
const team = await fetchTeam(id)
if (!team) {
redirect('/login')
}
// ...
}import { redirect } from 'next/navigation'
async function fetchTeam(id) {
const res = await fetch('https://...')
if (!res.ok) return undefined
return res.json()
}
export default async function Profile({ params }) {
const { id } = await params
const team = await fetchTeam(id)
if (!team) {
redirect('/login')
}
// ...
}须知:
redirect不需要您使用return redirect(),因为它使用了 TypeScript 的never类型。
redirect 可以直接在客户端组件中使用。
'use client'
import { redirect, usePathname } from 'next/navigation'
export function ClientRedirect() {
const pathname = usePathname()
if (pathname.startsWith('/admin') && !pathname.includes('/login')) {
redirect('/admin/login')
}
return <div>Login Page</div>
}'use client'
import { redirect, usePathname } from 'next/navigation'
export function ClientRedirect() {
const pathname = usePathname()
if (pathname.startsWith('/admin') && !pathname.includes('/login')) {
redirect('/admin/login')
}
return <div>Login Page</div>
}须知:当在服务器端渲染 (SSR) 期间的初始页面加载时在客户端组件中使用
redirect,它将执行服务器端重定向。
redirect 可以通过服务器操作在客户端组件中使用。如果您需要使用事件处理器来重定向用户,您可以使用 useRouter 钩子。
'use client'
import { navigate } from './actions'
export function ClientRedirect() {
return (
<form action={navigate}>
<input type="text" name="id" />
<button>Submit</button>
</form>
)
}'use client'
import { navigate } from './actions'
export function ClientRedirect() {
return (
<form action={navigate}>
<input type="text" name="id" />
<button>Submit</button>
</form>
)
}'use server'
import { redirect } from 'next/navigation'
export async function navigate(data: FormData) {
redirect(`/posts/${data.get('id')}`)
}'use server'
import { redirect } from 'next/navigation'
export async function navigate(data) {
redirect(`/posts/${data.get('id')}`)
}redirect 使用 307 和 308?当使用 redirect() 时,您可能会注意到使用的状态码是 307 用于临时重定向,308 用于永久重定向。虽然传统上 302 用于临时重定向,301 用于永久重定向,但许多浏览器在使用 302 时,无论原始请求方法是什么,都将重定向的请求方法从 POST 更改为 GET 请求。
以从 /users 重定向到 /people 的示例为例,如果您向 /users 发送 POST 请求以创建新用户,并符合 302 临时重定向,则请求方法将从 POST 更改为 GET 请求。这是没有意义的,因为要创建新用户,您应该向 /people 发送 POST 请求,而不是 GET 请求。
引入 307 状态码意味着请求方法将保留为 POST。
POST 更改为 GETPOSTredirect() 方法默认使用 307,而不是 302 临时重定向,这意味着您的请求将_始终_保留为 POST 请求。
了解更多 关于 HTTP 重定向的信息。
| 版本 | 更改 |
|---|---|
v13.0.0 | 引入了 redirect。 |