使用NextJS中间件进行重定向,特定页面除外

ctrmrzij  于 2023-10-18  发布在  其他
关注(0)|答案(1)|浏览(171)

我知道有很多关于这个主题的帖子,但没有专门针对这个问题的。
我使用的是T3堆栈,在开发应用程序的同时,我希望所有客户端请求都指向一个特定的路由,在本例中为/signup
我写了这个,这个工作:

export function middleware(request: NextRequest) {   
    const url = request.nextUrl.clone()
    if (!url.pathname.startsWith('/signup') && // exlude the signup page to avoid redirect loop
        !url.pathname.startsWith('/_next') && // exclude Next.js internals
        !url.pathname.startsWith('/_axiom') && // exclude Axiom
        !url.pathname.startsWith('/_api') && // exclude all API routes
        !url.pathname.includes('.')) // exclude public files
    {
        url.pathname = '/signup'
        return NextResponse.redirect(url)   
    } 
}

这是相当复杂的,但我宁愿使用matcher,如果我可以这样做。
我试过这个:

export function middleware(request: NextRequest) { 
    return NextResponse.redirect(new URL("/signup", request.url));
}

export const config = {
  matcher: [
    "/((?!signup|_axiom|_api|_next/static|_next/image).*)",
  ],
};

这似乎没有像我期望的那样选择匹配器,但是中间件和配置都被读取了。如果我删除配置,重定向尝试,但失败了太多的尝试。
理想情况下,我想使用类似于第二个选项的东西,特别是如果条件变得更加复杂。
谢谢你,

ufj5ltwl

ufj5ltwl1#

您可以尝试并测试一种更简洁的方法来实现您的目标,同时仍然保持middleware中的逻辑:使用正则表达式(regex)来测试请求的路径名。

export function middleware(request: NextRequest) {
    const url = request.nextUrl.clone();
    const excludedPaths = /^(\/signup|\/_next|\/_axiom|\/_api|.*\..*)/;
    if (!excludedPaths.test(url.pathname)) {
        url.pathname = '/signup';
        return NextResponse.redirect(url);
    }
}

这使用了正则表达式excludedPaths,创建该表达式是为了匹配应该从重定向中排除的路径。
test()方法用于检查url.pathname是否匹配任何排除的路径。
如果url.pathname不匹配任何排除的路径,则重定向到/signup
这种方法避免了一系列冗长的条件,应该提供一个更紧凑的解决方案。
也就是说,考虑到“How to use matcher in Next.js middleware“,对于Next.js版本12.2,middleware.ts文件应该放在项目根目录中,而对于版本13.1.6,它应该放在src目录中。
如果您使用的是Next.js版本13.1.6或类似版本,请按照建议将middleware.ts文件移动到src目录可能会解决此问题。
您可能需要调整matcher属性中的正则表达式,以确保它正确匹配您想要处理的路由。

// File path: <project-root>/src/middleware.ts

import { NextResponse, NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
    return NextResponse.redirect(new URL("/signup", request.url));
}

export const config = {
    matcher: new RegExp("/((?!signup|_axiom|_api|_next/static|_next/image).*)"),
};

这将把middleware.ts文件放置在Next.js版本13.1.6的src目录中,并更新matcher属性以使用RegExp对象而不是字符串。

相关问题