[Next.js篇] Next.js 跳转全家桶:redirect、permanentRedirect、NextResponse.redirect 与更多

2 分钟
28 阅读
[Next.js篇] Next.js 跳转全家桶:redirect、permanentRedirect、NextResponse.redirect 与更多

Next.js 跳转全家桶:redirect、permanentRedirect、NextResponse.redirect 与更多

在 Next.js(App Router)里,「跳转」并不是只有一把钥匙。
不同的 API 在「运行位置、HTTP 状态码、SEO 语义、回退行为」上差异巨大。
本文把官方 4 种写法 + 中间件用法整理成一张速查表,并给出实战代码,让你 3 分钟选对 API。


1 四把钥匙速查表

API 触发位置 HTTP 状态 SEO 语义 能否回退 典型场景
redirect('/new') Server Component / Route Handler 307 临时 暂时转移 登录校验、动态路由
permanentRedirect('/new') Server Component / Route Handler 308 永久 永久搬家 域名迁移、旧路由废弃
NextResponse.redirect('/new') middleware.js 307/308/301…(可传) 同上 同上 请求到达前统一拦截
<Link href="/new">useRouter().push() 浏览器 200(SPA 内) 不触发重定向 前端导航、无刷新

2 代码一图胜千言

2.1 服务端 307 / 308

ts 复制代码
// app/order/[id]/page.tsx
export default async function Page({ params }) {
  const valid = await checkOrder(params.id);
  if (!valid) {
    redirect('/404');               // 307
  }
  return <Order />;
}
ts 复制代码
// app/old-blog/[slug]/page.tsx
export default function Page() {
  permanentRedirect('/blog/new-slug'); // 308
}

2.2 中间件统一拦截

ts 复制代码
// middleware.ts
import { NextResponse } from 'next/server';

export function middleware(request) {
  const token = request.cookies.get('auth')?.value;

  // 未登录全部跳到登录页
  if (!token) {
    return NextResponse.redirect(new URL('/login', request.url), 307);
  }

  // 已登录但访问旧域名
  if (request.nextpathname.startsWith('/old')) {
    return NextResponse.redirect(new URL('/new', request.url), 308);
  }

  return NextResponse.next();
}

export const config = {
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};

3 什么时候选哪一个?

需求 推荐 API
登录页校验后跳转 redirect()
旧域名永久迁移 permanentRedirect()
统一鉴权 / A/B / 多域名重定向 NextResponse.redirect()
前端按钮、菜单 <Link>useRouter().push()

4 小结一句话

渲染层redirect/permanentRedirect网络层NextResponse.redirect交互层<Link>;选对位置,状态码和 SEO 就自然正确。

评论

评论

发表评论