nextjs 13应用程序目录中的多个中间件不工作

flseospp  于 2023-08-04  发布在  其他
关注(0)|答案(2)|浏览(174)

我使用的是Next.js 13,我为多语言设置了一个中间件功能。我想添加另一个中间件功能,但它对我不起作用。我想我在编写中间件时犯了一个错误,但我不确定是哪里。我没有得到任何错误,它只是不工作。
下面是我的代码:

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

import acceptLanguage from 'accept-language'
import { fallbackLng, languages } from './app/i18n/settings'

acceptLanguage.languages(languages)

const cookieName = 'i18next'

export function middleware(req: any) {
let lng
if (req.cookies.has(cookieName)) lng = acceptLanguage.get(req.cookies.get(cookieName).value)

    // automatic detect language with browser
    // if (!lng) lng = acceptLanguage.get(req.headers.get('Accept-Language'))
    
    if (!lng) lng = fallbackLng
    
    // Redirect if lng in path is not supported
    if (
        !languages.some(loc => req.nextUrl.pathname.startsWith(`/${loc}`)) &&
        !req.nextUrl.pathname.startsWith('/_next')
    ) {
        return NextResponse.redirect(new URL(`/${lng}${req.nextUrl.pathname}`, req.url))
    }
    
    if (req.headers.has('referer')) {
        const refererUrl = new URL(req.headers.get('referer'))
        const lngInReferer = languages.find((l) => refererUrl.pathname.startsWith(`/${l}`))
        const response = NextResponse.next()
        if (lngInReferer) response.cookies.set(cookieName, lngInReferer)
        return response
    }
    
    return NextResponse.next()

}

export function middleware2(request: NextRequest) {
if (request.nextUrl.pathname.startsWith('/about')){
return NextResponse.redirect(new URL('/home', request.url))
}

}

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

}

字符串

wnvonmuf

wnvonmuf1#

只能导出一个中间件函数。
来自Next.js 13文档

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
 
export function middleware(request: NextRequest) {
  if (request.nextUrl.pathname.startsWith('/about')) {
    return NextResponse.rewrite(new URL('/about-2', request.url))
  }
 
  if (request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.rewrite(new URL('/dashboard/user', request.url))
  }
}

字符串
在您的情况下,应该将middleware2中的条件移动到middleware

export function middleware(req: any) {
   // From middleware2
    
    if (request.nextUrl.pathname.startsWith('/about')){
        return NextResponse.redirect(new URL('/home', request.url))
    }

    let lng
    if (req.cookies.has(cookieName)) lng = acceptLanguage.get(req.cookies.get(cookieName).value)

    // automatic detect language with browser
    // if (!lng) lng = acceptLanguage.get(req.headers.get('Accept-Language'))
    
    if (!lng) lng = fallbackLng
    
    // Redirect if lng in path is not supported
    if (
        !languages.some(loc => req.nextUrl.pathname.startsWith(`/${loc}`)) &&
        !req.nextUrl.pathname.startsWith('/_next')
    ) {
        return NextResponse.redirect(new URL(`/${lng}${req.nextUrl.pathname}`, req.url))
    }
    
    if (req.headers.has('referer')) {
        const refererUrl = new URL(req.headers.get('referer'))
        const lngInReferer = languages.find((l) => refererUrl.pathname.startsWith(`/${l}`))
        const response = NextResponse.next()
        if (lngInReferer) response.cookies.set(cookieName, lngInReferer)
        return response
    }

    return NextResponse.next()

}


此外,配置没有api属性。matcher属性提供了在特定路由上运行中间件的选项。如果请求路径是/api/_next/static/_next/image/assets/favicon.ico/sw中的任何一个,则您的以下配置将阻止中间件运行

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

s1ag04yj

s1ag04yj2#

看起来你试图在同一个文件中使用两个中间件函数(middleware和middleware2)。然而,Next.js只允许每个文件导出一个中间件函数。
如果要使用多个中间件函数,则应该为每个中间件函数创建单独的文件。例如,您可以为第一个中间件函数创建一个middleware1.js文件,为第二个中间件函数创建一个middleware2.js文件。
下面是如何将中间件功能分离到两个文件中的方法:
middleware1.js

import { NextResponse, NextRequest } from 'next/server'
import acceptLanguage from 'accept-language'
import { fallbackLng, languages } from './app/i18n/settings'

acceptLanguage.languages(languages)

const cookieName = 'i18next'

export function middleware(req: any) {
  let lng
  if (req.cookies.has(cookieName)) lng = acceptLanguage.get(req.cookies.get(cookieName).value)

  if (!lng) lng = fallbackLng

  if (
    !languages.some(loc => req.nextUrl.pathname.startsWith(`/${loc}`)) &&
    !req.nextUrl.pathname.startsWith('/_next')
  ) {
    return NextResponse.redirect(new URL(`/${lng}${req.nextUrl.pathname}`, req.url))
  }

  if (req.headers.has('referer')) {
    const refererUrl = new URL(req.headers.get('referer'))
    const lngInReferer = languages.find((l) => refererUrl.pathname.startsWith(`/${l}`))
    const response = NextResponse.next()
    if (lngInReferer) response.cookies.set(cookieName, lngInReferer)
    return response
  }

  return NextResponse.next()
}

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

字符串
middleware2.js

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

export function middleware(request: NextRequest) {
  if (request.nextUrl.pathname.startsWith('/about')){
    return NextResponse.redirect(new URL('/home', request.url))
  }
}


请记住在应用程序的适当位置导入和使用这些中间件函数。

相关问题