You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vercel部署后无法重定向至目标页面问题求助

问题描述

访问受保护页面时会被重定向到登录页,原本预期将受保护页面URL存入查询参数,登录后自动跳转回该页面。此逻辑在本地开发环境正常,但部署到Vercel后,登录完成总是跳转到首页/。

相关代码片段:

Middleware 配置

// middleware.ts
const { pathname } = request.nextUrl;

if (!token && isLoginProtectedPath) {
  const redirectUrl = pathname;
  (await cookies()).set('redirect_url', redirectUrl);
  return NextResponse.redirect(new URL('/auth/login', request.url));
}

登录页逻辑

// login page
const searchParams = useSearchParams();

startTransition(async () => {
  const res = await login(payload);

  if (res.success) {
    setIsLogged(true);
    const redirectUrl = searchParams.get('redirect') || '/';
    console.log('login - redirectUrl', redirectUrl);
    router.push(redirectUrl);
    return;
  }
  toast.error(res.message);
});
问题根源
  1. 参数传递逻辑不匹配:Middleware中将目标页面URL存入了redirect_url Cookie,但登录页代码却尝试从URL查询参数redirect中取值,两边完全不对应,自然拿不到正确的跳转地址,最终 fallback 到首页。
  2. 本地环境可能因Cookie读取限制宽松偶然生效,但Vercel部署后,Cookie的跨域/环境适配问题导致无法正确读取,进一步加剧了这个问题。
修复方案

推荐采用URL查询参数传递跳转地址的方式,逻辑更直接且不易出问题:

步骤1:修改Middleware,将跳转地址附加到登录页URL

// middleware.ts
const { pathname } = request.nextUrl;

if (!token && isLoginProtectedPath) {
  // 构建登录页URL,并添加redirect查询参数
  const loginRedirectUrl = new URL('/auth/login', request.url);
  loginRedirectUrl.searchParams.set('redirect', pathname);
  return NextResponse.redirect(loginRedirectUrl);
}

步骤2:保持登录页逻辑不变(可选添加校验)

登录页原本从searchParams.get('redirect')取值的逻辑现在可以正常工作。如果需要防止恶意跳转,可添加地址白名单校验:

// login page
const searchParams = useSearchParams();

startTransition(async () => {
  const res = await login(payload);

  if (res.success) {
    setIsLogged(true);
    let redirectUrl = searchParams.get('redirect') || '/';
    // 校验跳转地址是否在允许范围内(可选)
    const allowedPaths = ['/dashboard', '/profile', '/orders'];
    if (!allowedPaths.includes(redirectUrl) && !redirectUrl.startsWith('/app/')) {
      redirectUrl = '/';
    }
    router.push(redirectUrl);
    return;
  }
  toast.error(res.message);
});

如果坚持使用Cookie传递方式,需修改登录页从Cookie中取值:

// login page(App Router 示例)
import { cookies } from 'next/headers';

startTransition(async () => {
  const res = await login(payload);

  if (res.success) {
    setIsLogged(true);
    // 从Cookie获取跳转地址
    const redirectUrl = cookies().get('redirect_url')?.value || '/';
    // 清除Cookie避免重复使用
    cookies().delete('redirect_url');
    router.push(redirectUrl);
    return;
  }
  toast.error(res.message);
});
额外注意事项
  • 部署到Vercel后,确保isLoginProtectedPath的路径匹配逻辑正确,避免因生产环境路径差异导致保护规则失效。
  • 若使用Cookie传递,需注意Vercel部署环境的Cookie配置(如domain、path),确保客户端能正确读取。

内容的提问来源于stack exchange,提问作者Mahadi Hasan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 01:27:05