redirect

redirect 函数允许你将用户重定向到另一个 URL。该函数可用于服务端组件 (Server Components)路由处理器 (Route Handlers)服务端操作 (Server Actions)

流式上下文 (streaming context) 中使用时,会插入一个 meta 标签在客户端触发重定向。在服务端操作中使用时,会向调用方返回 303 HTTP 重定向响应。其他情况下会返回 307 HTTP 重定向响应。

如果资源不存在,可以使用 notFound 函数 替代。

须知:

  • 在服务端操作和路由处理器中,redirect 应在 try/catch 代码块之后调用。
  • 若希望返回 308(永久)HTTP 重定向而非 307(临时),可使用 permanentRedirect 函数

参数

redirect 函数接受两个参数:

redirect(path, type)
参数类型描述
pathstring要重定向到的 URL,可以是相对路径或绝对路径。
type'replace'(默认值)或 'push'(服务端操作中默认值)指定重定向类型。

默认情况下,redirect服务端操作 (Server Actions) 中使用 push(在浏览器历史记录栈中添加新条目),在其他场景使用 replace(替换浏览器历史记录栈中的当前 URL)。可通过指定 type 参数覆盖此行为。

在服务端组件中使用时,type 参数不会产生任何效果。

返回值

redirect 不返回任何值。

示例

服务端组件

调用 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')
  }

  // ...
}

须知:由于使用了 TypeScript 的 never 类型,redirect 不需要使用 return redirect()

客户端组件

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>
}

须知:在服务端渲染 (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>
  )
}

常见问题

为什么 redirect 使用 307 和 308?

使用 redirect() 时,您可能会注意到临时重定向使用 307 状态码,永久重定向使用 308。传统上临时重定向使用 302,永久重定向使用 301,但许多浏览器在使用 302 时会将请求方法从 POST 改为 GET,无论原始请求方法是什么。

以从 /users 重定向到 /people 为例:如果您向 /users 发起 POST 请求创建新用户,并遵循 302 临时重定向,请求方法会从 POST 变为 GET。这显然不合理,因为创建新用户应该向 /people 发起 POST 请求而非 GET 请求。

307 状态码的引入确保了请求方法(如 POST)会被保留。

  • 302 - 临时重定向,会将 POST 请求方法改为 GET
  • 307 - 临时重定向,会保留 POST 请求方法

redirect() 方法默认使用 307 而非 302 临时重定向,这意味着您的请求方法将始终保留为 POST

了解更多关于 HTTP 重定向的信息。

版本历史

版本变更
v13.0.0引入 redirect

On this page