Nextjs 构建应用基础: 路由和中间件

一、路由(以App Router为例):

1.Nextjs使用项目目录结构去定义路由:

image.png

在对应路由文件夹下:

  • page.js文件定义页面
  • layout.js处理布局(page的内容会作为layout的children传入)
  • template.js(模板的路由之间导航时,会重新挂载children的新实例,创建 DOM 元素,不hi像布局一样维持状态)

image.png

其他特殊页面:
loading 展示loading、 error 展示错误等

2.重定向API

参考 Routing: Redirecting | Next.js (nextjs.org)

3.路由组

可以将项目文件按照一定逻辑去分组,同时避免影响页面路径:

image.png

4.平行路由

平行路由功能以插槽方式使用

image.png

其有如下使用方式:

  • 在layout内部有条件的显示页面

image.png

  • 允许为每个路由定义独立错误和加载页面

image.png

  • 插槽内添加子页面方便创建标签页组

image.png

import Link from 'next/link'
 
export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <>
      <nav>
        <Link href="/page-views">Page ViewsLink>
        <Link href="/visitors">VisitorsLink>
      nav>
      <div>{children}div>
    
  )
}

5.拦截路由

拦截路由时需要处理文件夹命名:

  • (.) 匹配同一层级
  • (..) 匹配上一层级
  • (..)(..) 匹配上上层级。
  • (...) 匹配根目录app

二、路由处理程序(以路由方式处理请求和响应):

路由处理程序需要名为router的文件,并且要在app目录下, 但是不能和page文件同目录:
支持这些HTTP方法:GETPOSTPUTPATCHDELETEHEADOPTIONS

1.路由处理程序的一些行为:

image.png

2.使用例子:

  • 可以使用增量静态重新生成 (ISR): 重新验证缓存的数据
  • Cookie:
    
    export async function GET(request) { 
        const token = request.cookies.get('token') 
        request.cookies.set(`token2`, 123) 
    }
    
    
        import { cookies } from 'next/headers'
    
        export async function GET(request) {
          const cookieStore = cookies()
          const token = cookieStore.get('token')
    
          return new Response('Hello, Next.js!', {
            status: 200,
            headers: { 'Set-Cookie': `token=${token}` },
          })
        }
    
    
  • Header
    import { headers } from 'next/headers'
    
        export async function GET(request: Request) {
          const headersList = headers()
          const referer = headersList.get('referer')
    
          return new Response('Hello, Next.js!', {
            status: 200,
            headers: { referer: referer },
          })
        }
    
    
        export async function GET(request) {
          const headersList = new Headers(request.headers)
          const referer = headersList.get('referer')
        }
    
  • 重定向
    import { redirect } from 'next/navigation' 
    export async function GET(request: Request) { 
        redirect('https://nextjs.org/')
    }
    
  • 获取动态路由值
    image.png
export async function GET(
  request: Request,
  { params }: { params: { slug: string } }
) {
  const slug = params.slug 
}
import { type NextRequest } from 'next/server'
 
export function GET(request: NextRequest) {
  const searchParams = request.nextUrl.searchParams
  const query = searchParams.get('query')
  
}
  • 支持流式处理
    流式处理
  • 获取请求体
    
    export async function POST(request: Request) {
    const res = await request.json()
    return Response.json({ res })
    
    
    export async function POST(request: Request) {
    const formData = await request.formData()
    const name = formData.get('name')
    const email = formData.get('email')
    return Response.json({ name, email })
    
  • 设置CORS
    export async function GET(request: Request) {
    return new Response('Hello, Next.js!', {
    status: 200,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type, Authorization',
    },
    })
    
  • 非UI内容返回
    export async function GET() {
          return new Response(
            `
        
    
        
          Next.js Documentation
          https://nextjs.org/docs
          The React Framework for the Web
        
    
        `,
            {
              headers: {
                'Content-Type': 'text/xml',
              },
            }
          )
    }
    

三、中间件

使用中间件可以拦截和处理应用中的请求和响应:
其应用场景包括:身份验证和授权服务器端重定向路径重写,爬虫程序检测,日志记录和分析,功能标记等;

1.定义中间件

在项目的根目录定义 middleware文件,例子如下:

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

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

export const config = {
  matcher: '/about/:path*',
}

上面将/about/路径重定向到home路径下

3.注意路由响应过程中对应配置的执行顺序

  1. headers(next.config.js
  2. redirects(next.config.js
  3. 中间件 (rewritesredirects 等)
  4. beforeFiles(next.config.jsrewrites)
  5. 文件系统的路由 (public/_next/static/pages/app/ )
  6. afterFiles (next.config.jsrewrites)
  7. 动态路由 (/blog/[slug])
  8. fallback (next.config.jsrewrites)

2.路径匹配器

  • 匹配单一路径或多个路径
export const config = {
  matcher: '/about/:path*',
  matcher: ['/about/:path*', '/dashboard/:path*'],
}
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))
  }
}

3.可以执行的操作

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
 
export function middleware(request: NextRequest) {
  
  
  let cookie = request.cookies.get('nextjs')
  console.log(cookie) 
  const allCookies = request.cookies.getAll()
  console.log(allCookies) 
 
  request.cookies.has('nextjs') 
  request.cookies.delete('nextjs')
  request.cookies.has('nextjs') 
 
  
  const response = NextResponse.next()
  response.cookies.set('vercel', 'fast')
  response.cookies.set({
    name: 'vercel',
    value: 'fast',
    path: '/',
  })
  cookie = response.cookies.get('vercel')
  console.log(cookie) 
  
 
  return response
}
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
 
export function middleware(request: NextRequest) {
  
  const requestHeaders = new Headers(request.headers)
  requestHeaders.set('x-hello-from-middleware1', 'hello')
 
  
  const response = NextResponse.next({
    request: {
      
      headers: requestHeaders,
    },
  })
 
  
  response.headers.set('x-hello-from-middleware2', 'hello')
  return response
}
import { NextRequest, NextResponse } from 'next/server'
 
const allowedOrigins = ['https://acme.com', 'https://my-app.org']
 
const corsOptions = {
  'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
  'Access-Control-Allow-Headers': 'Content-Type, Authorization',
}
 
export function middleware(request: NextRequest) {
  
  const origin = request.headers.get('origin') ?? ''
  const isAllowedOrigin = allowedOrigins.includes(origin)
 
  
  const isPreflight = request.method === 'OPTIONS'
 
  if (isPreflight) {
    const preflightHeaders = {
      ...(isAllowedOrigin && { 'Access-Control-Allow-Origin': origin }),
      ...corsOptions,
    }
    return NextResponse.json({}, { headers: preflightHeaders })
  }
 
  
  const response = NextResponse.next()
 
  if (isAllowedOrigin) {
    response.headers.set('Access-Control-Allow-Origin', origin)
  }
 
  Object.entries(corsOptions).forEach(([key, value]) => {
    response.headers.set(key, value)
  })
 
  return response
}
 
export const config = {
  matcher: '/api/:path*',
}
import type { NextRequest } from 'next/server'
import { isAuthenticated } from '@lib/auth'
 

export const config = {
  matcher: '/api/:function*',
}
 
export function middleware(request: NextRequest) {
  
  if (!isAuthenticated(request)) {
    
    return Response.json(
      { success: false, message: 'authentication failed' },
      { status: 401 }
    )
  }
}
  • 延长中间件的生命周期 类似await
import { NextResponse } from 'next/server'
import type { NextFetchEvent, NextRequest } from 'next/server'
 
export function middleware(req: NextRequest, event: NextFetchEvent) {
  event.waitUntil(
    fetch('https://my-analytics-platform.com', {
      method: 'POST',
      body: JSON.stringify({ pathname: req.nextUrl.pathname }),
    })
  )
 
  return NextResponse.next()
}

总结

在Next.js中,路由和中间件是构建应用的关键概念。通过App Directory,Next.js提供了灵活的路由系统,支持定义页面、布局和模板。平行路由允许开发者在同一个布局中同时或条件性地渲染多个页面,非常适合动态应用场景,如仪表板。路由处理程序则允许开发者在app目录下创建自定义的请求处理逻辑,支持多种HTTP方法,并能利用Next.js提供的扩展API。

中间件则为应用提供了在请求到达页面或API之前进行拦截和处理的能力,适用于身份验证、重定向、CORS设置等多种场景。开发者可以通过定义middleware.js文件来创建中间件,并利用Next.js提供的API进行复杂的请求处理。

阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.shuli.cc/?p=20872,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?