Next.js中_app.jsx内使用getInitialProps重定向触发无限循环的原因及解决方法
嘿,我刚好碰到过类似的问题,咱们来聊聊这个无限循环的根源和解决办法。
为什么会出现无限循环?
你的_app.jsx里的getInitialProps会在每一个页面的服务端渲染阶段都执行——包括你重定向到的/login页面。
当用户访问任意页面时,getInitialProps检测到ctx.res存在(服务端环境),就会触发重定向到/login;但用户被重定向到/login后,_app的getInitialProps又会再次执行,再次检测到ctx.res,又把用户重定向回/login……这样就形成了无限循环的闭环。
修复方案
方案1:在getInitialProps里判断当前路径(快速解决)
只需要在重定向逻辑前加一个判断:如果当前请求的路径已经是/login,就跳过重定向。修改后的代码如下:
const MyApp = ({ Component, pageProps }) => { return ( <> <Component {...pageProps} /> </> ); }; MyApp.getInitialProps = async ({ ctx }) => { console.log("run 1"); // 新增:只有当前路径不是/login时才执行重定向 if (ctx.pathname !== "/login" && ctx.res) { console.log("run here"); ctx.res.writeHead(302, { Location: "/login" }); ctx.res.end(); } return {}; }; export default MyApp;
这个改动的核心是通过ctx.pathname获取当前请求的页面路径,切断循环的触发条件——当用户到达/login后,重定向逻辑就不会再执行了。
方案2:用Next.js中间件(Middleware)处理全局重定向(推荐)
如果你用的是Next.js 12及以上版本,更推荐用Middleware来处理全局重定向逻辑,这比在_app里写getInitialProps更符合Next.js的最佳实践,也更灵活。
在项目根目录创建middleware.js文件:
import { NextResponse } from 'next/server'; export function middleware(request) { // 这里替换成你实际的登录状态判断逻辑(比如从cookie或session中读取) const isLoggedIn = false; // 如果未登录且当前不在/login页面,就重定向 if (!isLoggedIn && request.nextUrl.pathname !== '/login') { return NextResponse.redirect(new URL('/login', request.url)); } } // 指定需要应用中间件的路径(排除静态资源和API路由) export const config = { matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'], };
Middleware会在请求到达页面之前就执行,能更高效地处理全局路由拦截,而且不会像getInitialProps那样在每个页面都重复触发逻辑。
内容的提问来源于stack exchange,提问作者Maruko
相关产品推荐
相关产品推荐

