Menu

redirect

redirect 函数允许你将用户重定向到另一个 URL。redirect 可以在 服务器组件路由处理程序服务器操作 中使用。

当在 流式渲染上下文 中使用时,它会插入一个 meta 标签以在客户端执行重定向。当在服务器操作中使用时,它会向调用者返回一个 303 HTTP 重定向响应。在其他情况下,它会向调用者返回一个 307 HTTP 重定向响应。

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

值得注意的是:

  • 在服务器操作和路由处理程序中,redirect 应该在 try/catch 块之后调用。
  • 如果你希望返回 308 (永久) HTTP 重定向而不是 307 (临时),你可以使用 permanentRedirect 函数 代替。

参数

redirect 函数接受两个参数:

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

默认情况下,redirect服务器操作 中使用 push (在浏览器历史栈中添加新条目),在其他地方使用 replace (替换浏览器历史栈中的当前 URL)。你可以通过指定 type 参数来覆盖这种行为。

type 参数在服务器组件中使用时没有效果。

返回值

redirect 不返回任何值。

示例

服务器组件

调用 redirect() 函数会抛出一个 NEXT_REDIRECT 错误并终止渲染抛出该错误的路由段。

app/team/[id]/page.js
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 team = await fetchTeam(params.id);
  if (!team) {
    redirect("/login");
  }
 
  // ...
}

值得注意的是: redirect 不要求你使用 return redirect(),因为它使用 TypeScript never 类型。

客户端组件

redirect 可以通过服务器操作在客户端组件中使用。如果你需要使用事件处理程序来重定向用户,你可以使用 useRouter hook。

app/client-redirect.tsx
"use client";
 
import { navigate } from "./actions";
 
export function ClientRedirect () {
  return (
    <form action={navigate}>
      <input type="text" name="id" />
      <button>Submit</button>
    </form>
  );
}
app/client-redirect.jsx
"use client";
 
import { navigate } from "./actions";
 
export function ClientRedirect () {
  return (
    <form action={navigate}>
      <input type="text" name="id" />
      <button>Submit</button>
    </form>
  );
}
app/actions.ts
"use server";
 
import { redirect } from "next/navigation";
 
export async function navigate (data: FormData) {
  redirect(`/posts/${data.get("id")}`);
}
app/actions.js
"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

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

redirect() 方法默认使用 307 而不是 302 临时重定向,这意味着你的请求将始终保持为 POST 请求。

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

版本历史

版本变更
v13.0.0引入 redirect