我知道有很多关于这个话题的帖子,但没有专门针对这个问题的.

我正在使用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).*)",
  ],
};

这似乎没有以我期望的方式获得匹配器,但是中间件和配置都被读取了.如果我删除配置,则会try 重定向,但try 次数太多会失败.

理想情况下,我希望使用与第二个选项类似的选项,特别是在条件条件变得更加复杂的情况下.

谢谢,

推荐答案

您可以try 并测试一种更简洁的方法来实现您的目标,同时仍然将逻辑保持在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);
    }
}

This uses a regular expression excludedPaths, created to match the paths that should be excluded from redirection.
The test() method is used to check if url.pathname matches any of the excluded paths.
If url.pathname does not match any of the excluded paths, it is redirected to /signup.

这种方法避免了冗长的一系列条件条件,应该会提供更紧凑的解决方案.


That being said, considering "How to use matcher in Next.js middleware", for Next.js version 12.2, the middleware.ts file should be placed in the project root, while for version 13.1.6, it should be placed in the src directory.
If you are using Next.js version 13.1.6 or a similar version, moving the middleware.ts file to the src directory as suggested might resolve the issue.

您可能需要调整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对象而不是字符串.

Typescript相关问答推荐

Typescript如何从字符串中提取多个文本

相同端点具有不同响应时的RTKQuery类型定义

有没有办法适当缩小类型?

为什么ESLint抱怨通用对象类型?

如果在TypeScript中一个原始的类方法是递归的,如何使用类decorator 模式?

TypeScript类型不匹配:在返回类型中处理已经声明的Promise Wrapper

Next.js错误:不变:页面未生成

PrimeNG日历需要找到覆盖默认Enter键行为的方法

Material UI / MUI系统:我如何告诉TypeScript主题是由提供程序传递的?

如何在Typescript 中组合unions ?

在打印脚本中使用泛型扩展抽象类

如何使用泛型函数参数定义类型脚本函数

创建一个函数,该函数返回一个行为方式与传入函数相同的函数

如何在具有嵌套数组的接口中允许新属性

Cypress-验证别名的存在或将别名中的文本与';if';语句中的字符串进行比较

如何在Next.js和Tailwind.css中更改悬停时的字体 colored颜色

两个名称不同的相同打字界面-如何使其干燥/避免重复?

替换typescript错误;X类型的表达式可以';t用于索引类型Y;带有未定义

如何通过nx找到所有受影响的项目?

根据索引将元组拆分为两个块