Next.js 中的“前端路由”和“后端路由”到底是怎么回事?
让我为你整理一套结构清晰、概念分明的参考。
🗺️ 1. 概述
Next.js 是一个同构框架,同时跑在:
- 🖥️ 客户端(浏览器,前端路由)
- ⚡️ 服务端(Node.js,后端路由)
👉 在这种情况下,路由分为:
- 前端路由:页面之间的切换。
- 后端路由:处理服务器请求,比如接口(API Route)、页面构建。
🌐 2. 前端路由
概念
- 在客户端控制页面之间的跳转。
- 用
app
或pages
结构中的Link
组件和useRouter()
实现。 - 路径完全对齐
app
/pages
结构。
例子
用 Link 跳转页面
import Link from 'next/link';export default function Home() {return (<div><Link href="/about">About</Link></div>);
}
用 useRouter 跳转
'use client';
import { useRouter } from 'next/navigation';export default function Demo() {const router = useRouter();return (<button onClick={() => router.push('/blog')}>Go to Blog</button>);
}
特点
✅ 完成页面之间的跳转,无需重新请求服务器。
✅ 跳转迅速(因为是单页面应用行为)。
✅ 路由结构和app
或pages
目录结构同步。
⚡️ 3. 后端路由
概念
-
在服务器端处理请求。
-
用于:
- 获取数据库数据。
- 创建 REST 接口。
- 获取第三方数据。
-
在
app
中为路由处理器,通常放在:app/api/.../route.ts
-
在
pages
结构里通常是:pages/api/...js
示例
在 app/api
中:
// app/api/hello/route.ts
import { NextResponse } from 'next/server';export async function GET() {return NextResponse.json({ message: 'Hello, Next.js' });
}
调用:
GET http://localhost:3000/api/hello
在 pages/api
中:
// pages/api/hello.js
export default function handler(req, res) {res.status(200).json({ message: 'Hello from Pages API' });
}
调用:
GET http://localhost:3000/api/hello
特点
✅ 跑在服务器,完全隔离于前端。
✅ 可做数据库查询、第三方接口调用。
✅ 可对请求做认证、授权。
🗺️ 4. 对比总结
对比 | 前端路由 | 后端路由 |
---|---|---|
执行位置 | 客户端(浏览器) | 服务端(Node.js) |
用途 | 渲染页面、页面之间导航 | 获取数据、处理接口请求 |
路径结构 | app/... 、pages/... 对应页面 | app/api/... 、pages/api/... 对应接口 |
跳转方式 | Link 、useRouter() | AJAX、fetch、POST 请求 |
刷新页面? | 否(单页面应用) | 可配置是否重新渲染页面 |
⚡️ 5. 场景示例
场景 | 用途 | 用什么路由? |
---|---|---|
点击页面之间的链接 | 前端页面之间切换 | ✅ 前端路由 |
获取数据库中的文章列表 | 获取后端数据 | ✅ 后端路由 (/app/api/… 或 /pages/api/…) |
在页面中提交表单后保存数据 | 向后端提交 | ✅ 后端路由 + fetch/AJAX |
在页面之间以参数显示不同内容 | 路由参数 | ✅ 前端路由 (app/[param]) |
获取第三方接口数据后展示 | 请求后端接口 | ✅ 后端路由 (调用第三方接口) |
🔥 简单示意
[ 客户端 ] ----点击Link---> [ Next.js 前端路由 ] ---> 渲染页面↓ 请求接口
[ 客户端 ] ----fetch()----> [ Next.js 后端路由 ] ---> 获取/处理数据
很好,我已经为你整理好了Next.js 完整的路由结构示例代码和参数解析示例。
以下示例针对 App Router 架构(app/
目录),因为这是 Next.js 当前重点推荐的结构。
📂 完整结构示例
app/
├─ layout.tsx # 顶层Layout,适配所有页面
├─ page.tsx # 首页 (app/)
├─ about/
│ └─ page.tsx # 静态页面 (/about/)
├─ blog/
│ └─ page.tsx # 博客列表 (/blog/)
├─ blog/
│ └─ [slug]/
│ └─ page.tsx # 博客详情 (/blog/my-first-post/)
├─ api/
│ └─ hello/
│ └─ route.ts # REST接口 (/api/hello/)
├─ api/
│ └─ posts/
│ └─ [id]/
│ └─ route.ts # REST接口 (/api/posts/123/)
⚡️ 路由类型概览
路由类型 | 路径示例 | 用途 |
---|---|---|
静态页面 | /about | 简单页面 |
动态页面 | /blog/[slug] | 可变参数页面 |
静态接口 | /api/hello | 简单后端接口 |
动态接口 | /api/posts/[id] | 可变参数接口 |
✅ 各类型参数解析代码示例
1️⃣ 静态页面
结构: app/about/page.tsx
export default function AboutPage() {return <h1>About Us</h1>;
}
2️⃣ 动态页面参数
结构: app/blog/[slug]/page.tsx
interface PageProps {params: {slug: string;};
}export default function BlogPost({ params }: PageProps) {return <h1>Blog Post: {params.slug}</h1>;
}
访问示例:
http://localhost:3000/blog/my-first-post
3️⃣ 静态接口
结构: app/api/hello/route.ts
import { NextResponse } from 'next/server';export async function GET() {return NextResponse.json({ message: 'Hello, Next.js API Route!' });
}
调用:
GET http://localhost:3000/api/hello
4️⃣ 动态接口参数
结构: app/api/posts/[id]/route.ts
import { NextResponse } from 'next/server';export async function GET(request: Request, { params }: { params: { id: string } }) {const postId = params.id;return NextResponse.json({ postId, message: 'Post data here' });
}
调用:
GET http://localhost:3000/api/posts/123
⚡️ 获取查询参数示例
如果接口是:
GET http://localhost:3000/api/hello?name=John
结构: app/api/hello/route.ts
import { NextResponse } from 'next/server';export async function GET(request: Request) {const url = new URL(request.url);const name = url.searchParams.get('name') || 'Guest';return NextResponse.json({ message: `Hello, ${name}!` });
}
🗺️ 路由参数总结表
类型 | 获取方式 | 示例代码片段 |
---|---|---|
静态页面 | 无参数 | app/about/page.tsx |
动态页面参数 | params.{paramName} | app/blog/[slug]/page.tsx |
静态接口参数 | 无参数 | app/api/hello/route.ts |
动态接口参数 | params.{paramName} | app/api/posts/[id]/route.ts |
接口查询参数 | new URL(request.url).searchParams.get() | app/api/hello/route.ts 获取查询参数 name |