路由入门:从零理解前端路由和后端路由

0 阅读4分钟

前言

先交代下背景:我大二才转到计算机,之前就会写点静态页面。最近想做个校园论坛,结果瞬间被三个问题卡住了脖子:

  • 我想点击导航栏切换内容,但不想整个页面刷新(单页应用体验)。
  • 我想让用户直接访问 /post/123 就能看到对应帖子详情。
  • 我还需要写后端接口,让前端能登录、注册、发帖。

琢磨了一圈,发现这三个问题全指向同一个东西——路由。学完之后我觉得路由真没想象中那么抽象,而且前端和后端的路由思想是通的。这篇文章就当是我的学习笔记,希望能帮到同样困惑的你。

F51F20A9DC52D2C27E207562A5F7A511.gif


1. 什么是路由?

想象你去酒店,前台问:“先生,您的房号是?”你说“602”,然后服务员带你到602房间。

  • 房号 = 路径
  • 服务员 = 路由器
  • 602房间 = 处理结果

在 Web 开发里,路由就是:根据请求的 URL(以及 HTTP 方法),找到对应的处理函数,然后返回页面、数据或者 JSON。


2. 前端路由和后端路由分别干嘛?

前端路由(Vue Router / React Router)

  • 场景:单页应用(SPA),页面不刷新就切换内容。
  • 原理:监听 URL 变化,渲染对应的组件。

后端路由(Express / Koa)

  • 场景:提供 API 接口,或者返回不同的 HTML 页面。
  • 原理:服务器收到请求,匹配路径和方法,执行代码,返回响应。

这篇文章我会把前端路由带一遍(因为很常用),但重点放在 Express 后端路由上。


3. 前端路由速览(Vue Router)

这块简单过一下,但基础用法要知道。已经了解的同学可以跳过·这一段。

3.1 安装配置

npm install vue-router

src/router/index.js

import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About },
  { path: '/post/:id', component: () => import('../views/PostDetail.vue') }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

3.2 跳转和获取参数

<template>
  <router-link to="/">首页</router-link>
  <button @click="$router.push('/post/123')">去帖子</button>
</template>

在 PostDetail.vue 里拿参数:

import { useRoute } from 'vue-router'
const route = useRoute()
const postId = route.params.id  // 123

3.3 一个前端踩坑:部署后刷新404

项目部署到 Vercel 上,点击路由跳转正常,但一刷新页面就 404。

原因:Vercel 默认只认真实文件路径,不认识前端路由的虚拟路径。

解决:项目根目录加 vercel.json

{
  "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}

意思是所有请求都返回 index.html,剩下的交给 Vue Router。


4. 重点:后端路由(Express 实战)

下面就是这次的重头戏,也是我踩坑最多的地方。

4.1 搭一个最简单的服务器

npm init -y
npm install express cors

index.js

const express = require('express')
const cors = require('cors')
const app = express()
const port = 3000

app.use(cors())
app.use(express.json()) // 千万别忘,后面会说

app.get('/', (req, res) => {
  res.send('Hello World')
})

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`)
})

4.2 不同 HTTP 方法的路由

// 获取帖子列表
app.get('/posts', (req, res) => {
  res.json([{ id: 1, title: '帖子1' }])
})

// 创建新帖子
app.post('/posts', (req, res) => {
  const { title, content } = req.body
  // 存数据库...
  res.status(201).json({ message: '创建成功' })
})

// 更新帖子
app.put('/posts/:id', (req, res) => {
  const { id } = req.params
  res.send(`更新帖子 ${id}`)
})

// 删除帖子
app.delete('/posts/:id', (req, res) => {
  const { id } = req.params
  res.send(`删除帖子 ${id}`)
})

4.3 获取参数的三种姿势

  • 路径参数/user/:id → req.params.id
  • 查询参数/search?keyword=vue → req.query.keyword
  • 请求体:POST 请求 JSON → req.body

4.4 路由模块化(express.Router

项目大了不能全写在一个文件里,就可以用 Router 拆分一下。

routes/user.js

const express = require('express')
const router = express.Router()

router.post('/login', (req, res) => {
  res.send('登录成功')
})
router.post('/register', (req, res) => {
  res.send('注册成功')
})

module.exports = router

index.js 挂载:

const userRouter = require('./routes/user')
app.use('/user', userRouter)  // 最终路径:/user/login, /user/register

4.5 后端踩坑合辑

⚠️ 坑1:req.body 一直是 undefined

前端明明发了请求,后端 console.log(req.body) 却是 undefined

原因:忘了加 app.use(express.json()) 中间件。

解决:在路由前加上这一行。这个坑我起码踩过三次,现在写 Express 第一件事就是检查这行有没有写。

⚠️ 坑2:路由顺序写错,导致匹配混乱

比如我写了:

app.get('/user/:id', ...)      // 动态路由
app.post('/user/login', ...)   // 具体路由

访问 /user/login 的时候,Express 会先匹配到 /user/:id,然后把 login 当成 id 参数,导致登录逻辑根本不执行。

解决:把具体路径写在动态路径前面。

app.post('/user/login', ...)   // 具体路径在前
app.get('/user/:id', ...)      // 动态路径在后

5. 前后端路由的简单对比

维度前端路由(Vue Router)后端路由(Express)
运行环境浏览器服务器
触发方式点击链接、router.pushHTTP 请求
参数传递paramsqueryparamsquerybody
响应内容渲染组件JSON 或 HTML
拦截机制beforeEach 守卫中间件 app.use()

虽然环境不同,但核心思想完全一样:路径 → 处理函数。理解了一个,另一个上手就很快。


6. 最后想说的

路由这玩意儿,光看概念会觉得有点难以理解,真上手写一遍就明白了。我写这篇笔记的时候,已经把我踩过的坑都尽量标出来了,希望你不用再掉进去。

现在我的校园论坛项目还在修修补补,但起码路由这部分心里有底了。如果你也是初学者,建议把上面的代码自己敲一遍,尤其是 Express 那几段。

对了,你刚学路由的时候,踩过哪些想摔键盘的坑?评论区分享一下,让我知道我不是一个人 😂

Happy Coding!

2BD007AA306B307E8EC12896555B355F.gif