一、路由(以App Router为例):
1.Nextjs使用项目目录结构去定义路由:
在对应路由文件夹下:
page.js
文件定义页面layout.js
处理布局(page的内容会作为layout的children传入)template.js
(模板的路由之间导航时,会重新挂载children的新实例,创建 DOM 元素,不hi像布局一样维持状态)
其他特殊页面:
loading
展示loading、 error
展示错误等
2.重定向API
参考 Routing: Redirecting | Next.js (nextjs.org)
3.路由组
可以将项目文件按照一定逻辑去分组,同时避免影响页面路径:
4.平行路由
平行路由功能以插槽方式使用
其有如下使用方式:
- 在layout内部有条件的显示页面
- 允许为每个路由定义独立错误和加载页面
- 插槽内添加子页面方便创建标签页组
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方法:GET
, POST
, PUT
, PATCH
, DELETE
, HEAD
, OPTIONS
1.路由处理程序的一些行为:
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/') }
- 获取动态路由值
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/docsThe React Framework for the Web
三、中间件
使用中间件可以拦截和处理应用中的请求和响应:
其应用场景包括:身份验证和授权
、服务器端重定向
、路径重写
,爬虫程序检测
,日志记录和分析
,功能标记
等;
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.注意路由响应过程中对应配置的执行顺序
- headers(
next.config.js
) - redirects(
next.config.js
) - 中间件 (
rewrites
,redirects
等) - beforeFiles(
next.config.js
中rewrites
) - 文件系统的路由 (
public/
,_next/static/
,pages/
,app/
) - afterFiles (
next.config.js
中rewrites
) - 动态路由 (
/blog/[slug]
) - fallback (
next.config.js
中rewrites
)
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,转载请注明出处。
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.shuli.cc/?p=20872,转载请注明出处。
评论0