WEB开发: Node.js路由之由浅入深(一) - 全栈工程师入门
作为一个使用Node.js多年的开发者,我已经习惯于用Node.js写一些web应用来为工作服务,因为实现快速、部署简单、自定义强。今天我们一起来学习一个全栈工程师必备技能:web路由。(观看此文的前提是默认你已经装好nonde.js了)
Node.js 中的路由是构建 Web 应用的核心概念之一,帮助我们根据用户请求的 URL 和 HTTP 方法(GET、POST 等)做出不同的响应。
下面我们由浅入深,循序渐进地讲解 Node.js 的路由实现:
1. 什么是路由?
【路由(Routing)】是指确定服务器响应用户请求的方式,也就是你访问网站的哪个路径,服务器根据路径响应你相应的内容。
比如某网站 www.duniang.com/路由1 、 www.duniang.com/路由1/路由1的儿子
路由主要根据两个要素:
- 请求的 URL(如
/home或/about) - 请求的方法(如
GET、POST、PUT、DELETE)
关于这一点网上有很多讨论,很多人基本就是 GET / POST 一招吃遍天下,这也无可厚非。不过建议开发者还是老老实实 规规矩矩的把习惯养好,该PUT就PUT 该DELETE就DELETE。
2. 用原生 Node.js 实现简单路由
用原生的 http 模块,我们可以通过检查请求的 URL 和方法来实现路由。以下是一个简单的例子:
const http = require('http');const server = http.createServer((req, res) => {const { url, method } = req;if (url === '/' && method === 'GET') {res.writeHead(200, { 'Content-Type': 'text/plain' });res.end('Welcome to Home Page');} else if (url === '/about' && method === 'GET') {res.writeHead(200, { 'Content-Type': 'text/plain' });res.end('This is the About Page');} else {res.writeHead(404, { 'Content-Type': 'text/plain' });res.end('Page Not Found');}
});server.listen(3000, () => {console.log('Server running at http://localhost:3000/');
});
特点:
- 手动判断
url和method。 - 适合学习,但不适合复杂应用,代码难以维护。
http是node内核自带的网络服务模块,可以快速创建http服务。
将上面代码命名为 app.js ,使用 node app.js 命令 启动
创建了一个端口为3000的 webServer,我我们可以通过 http://127.0.0.1:3000访问:

3. 使用 Express 简化路由
http 这个模块使用起来还是不太方便,观感不太好,代码量也比较大,如果路由复杂,要写很多代码。所以就有了 Express
Express 是一个轻量级、流行的 Node.js 框架,它对路由的处理非常直观。我们可以用它创建清晰、可扩展的路由。
安装 Express:
npm install express
简单路由示例:
const express = require('express');
const app = express();app.get('/', (req, res) => {res.send('Welcome to Home Page');
});app.get('/about', (req, res) => {res.send('This is the About Page');
});// 404 handler
app.use((req, res) => {res.status(404).send('Page Not Found');
});app.listen(3000, () => {console.log('Server running at http://localhost:3000/');
});
优点:
- 简洁的 API,如
app.get()、app.post()。 - 支持中间件,可以扩展功能(如验证、日志)。
上面这个代码就清楚多了。 Express在现实中的应用非常广泛,它简单、直观,使用起来也很灵活。
4. 动态路由
动态路由允许我们为具有相似结构的 URL 创建单一路由。例如,处理用户的 ID:
app.get('/user/:id', (req, res) => {const userId = req.params.id; // 获取动态参数res.send(`User ID is ${userId}`);
});
访问 http://localhost:3000/user/123,响应为:
User ID is 123

请注意,这里的网址是 /user/minstbe 后面这个/minstbe 本来应该是一个路由,但是这里被定义为一个参数 ,它等效于 /user?id=minstbe 。很多时候我们如果不希望网页带有问号、等于号,就可以用这种方式来定义传参。
req.params:存储动态 URL 参数。
如果我们在服务器端 console.log(req.params) 就会看到打印出了这个Object类型的参数:

5. 路由模块化
当路由逻辑增多时,我们可以将路由分离到单独的文件中,提高代码的可读性和可维护性。实际生产过程中,还会用到更加高级的分离方式 这个我们以后再介绍。
1. 创建路由模块(routes/user.js):
在webServer的主目录下创建 文件夹 routes ,并创建user.js,用来对 /user做出响应
const express = require('express');
const router = express.Router();router.get('/:id', (req, res) => {const userId = req.params.id;res.send(`User Profile of ID: ${userId}`);
});module.exports = router;
2. 在主文件中引入路由模块(index.js):
const express = require('express');
const app = express();
const userRoutes = require('./routes/user'); // 这里引入了这个路由模块app.use('/user', userRoutes); // 访问路径为 /user/:idapp.listen(3000, () => {console.log('Server running at http://localhost:3000/');
});
上面两个文件结合使用,启动index.js 后如下:

6. 中间件与路由结合
中间件是在路由处理前或后执行的一段代码,用于实现日志、验证、解析等功能。
中间件在Node.js的webServer中非常重要,很多功能都是在中间件实现的,通过中间件处理获取到的内容,再交给后面的api来处理。
示例:
const logger = (req, res, next) => {console.log(`${req.method} ${req.url}`);next(); // 必须调用 next() 才能进入下一个中间件或路由
};app.use(logger);app.get('/', (req, res) => {res.send('Home Page with Logger');
});
下面是在/user 之前 加入了一个中间件,也就是显示 访问方式 和 路径,然后再继续 交给 /user判断处理:(请注意控制台的输出)

7. 高级路由功能
- 处理多种 HTTP 方法:
app.route('/book').get((req, res) => res.send('Get a book')).post((req, res) => res.send('Add a book')).put((req, res) => res.send('Update a book'));
app.route() 是 Express 提供的一个链式路由定义方法,用于处理针对 同一路径 的多个 HTTP 方法(如 GET、POST、PUT 等)的请求。
工作原理
app.route(path) 会创建一个单独的路由路径对象,可以通过链式调用分别为该路径定义不同的 HTTP 方法处理逻辑。这种写法能使代码更加清晰、结构更紧凑。
具体解析
app.route('/book').get((req, res) => res.send('Get a book')).post((req, res) => res.send('Add a book')).put((req, res) => res.send('Update a book'));
-
app.route('/book')
定义了一个路径/book的路由。 -
.get()- 处理
GET /book请求。 - 回调函数
(req, res)用于返回一个响应,当前返回内容是'Get a book'。
- 处理
-
.post()- 处理
POST /book请求。 - 回调函数
(req, res)返回'Add a book'。
- 处理
-
.put()- 处理
PUT /book请求。 - 回调函数
(req, res)返回'Update a book'。
- 处理
等价写法
上述代码的功能可以用多个单独的路由来实现:
app.get('/book', (req, res) => res.send('Get a book'));
app.post('/book', (req, res) => res.send('Add a book'));
app.put('/book', (req, res) => res.send('Update a book'));
对比:
- 使用
app.route()方法:- 逻辑集中在一个地方,便于管理和阅读。
- 适合路径相同但处理方法不同的场景。
- 使用分开定义的路由:
- 路径重复,代码冗长,不够直观。
扩展:何时使用 app.route()?
- 当一个路径需要支持多种 HTTP 方法时,比如
/book需要处理GET、POST和PUT。 - 希望减少路径的重复书写,提高代码可读性和组织性。
注意:
app.route()仅适用于同一个路径。如果处理的路径不同(比如/book和/author),仍需单独定义路由。- 它仅是 Express 提供的一种语法糖,本质上和单独写多个路由的逻辑一样。
- 正则匹配路由:
app.get(/.*fly$/, (req, res) => {res.send('Route matched with /.*fly$/');
});
// 例如,访问 /butterfly、/dragonfly 都可以匹配
好了 今天,就简单介绍一下,下次再继续!
- 原生实现:适合理解底层原理。
- Express:简化路由逻辑,是构建 Web 应用的主流选择。
- 动态路由:为类似的请求模式处理提供便利。
- 模块化路由:适合复杂项目。
- 中间件支持:增强功能的可扩展性。
可以从简单的例子开始尝试,然后逐渐增加复杂度,适应实际的开发场景!你想尝试哪种实现?
相关文章:
WEB开发: Node.js路由之由浅入深(一) - 全栈工程师入门
作为一个使用Node.js多年的开发者,我已经习惯于用Node.js写一些web应用来为工作服务,因为实现快速、部署简单、自定义强。今天我们一起来学习一个全栈工程师必备技能:web路由。(观看此文的前提是默认你已经装好nonde.js了…...
NES游戏机项目制作笔记(未完成)
24年12月1日晚记——在网上找项目学习的时候发现一个有意思的项目,准备靠这个应用一些STM32的高级功能。值得提醒的是——目的在于学习不可贪杯,注意效率 01 根据项目需求分析 为确保充分考虑每一个细节,并且让自己高效的完成项目制作&#…...
云服务器部署upload-labs-docker(文件上传靶场)环境 以及相关报错问题
环境的搭建 准备:云服务器(本地的linux服务器(版本最好不要是老的不然不兼容docker)) f8x配置docker环境: https://github.com/ffffffff0x/f8x 一键配置 docker拉取file-labs靶场 https://github.com…...
Elasticsearch入门之HTTP基础操作
RESTful REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。Web 应用程序最重要的 REST 原则是,客户端和服务器之间的交互在请求之间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在…...
maven聚合项目部署到tomcat上
目录 一.聚合项目 1.检查无误后将项目打包 2.将这四个拷贝到tomcat的webapp下 二.启动tomcat 1.双击startup.bat 2.页面访问http://localhost:8080 3.打开webapp文件夹,发现多了三个文件夹 4.点进去才有要访问的index页面 5.再进行访问 解决: …...
基于Matlab生育模型和年龄别死亡率的未来人口预测与结构动态分析
人口预测在社会经济发展、政策规划以及资源分配中扮演着至关重要的角色,特别是在全球人口老龄化、少子化趋势日益显著的背景下,对人口增长规律及结构变化的研究愈发重要。人口结构的变化不仅直接影响劳动力供给和经济增长潜力,还对医疗、教育…...
公共服务 kkFileView 4.1 文件预览 Docker 一键部署
官方文档 https://kkview.cn/zh-cn/docs/production.html 镜像导入 # 网络环境方便访问docker中央仓库 docker pull keking/kkfileview:4.1.0# 网络环境不方便访问docker中央仓库 wget https://kkview.cn/resource/kkFileView-4.1.0-docker.tar docker load -i kkFileView-4…...
福昕PDF低代码平台
福昕PDF低代码平台简介 福昕PDF 低代码平台是一款创新的工具,旨在简化PDF处理和管理的流程。通过这个平台,用户可以通过简单的拖拽界面上的按钮,轻松完成对Cloud API的调用工作流,而无需编写复杂的代码。这使得即使没有编程经验的…...
Ubuntu环境安装RabbitMQ
1.安装Erlang RabbitMq需要Erlang语⾔的⽀持,在安装rabbitMq之前需要安装erlang # 更新软件包 sudo apt-get update # 安装 erlang sudo apt-get install erlang 查看erlang版本 : erl 退出命令:halt(). 2. 安装RabbitMQ # 更新软件包 sudo apt-get update # 安装 …...
集合ArrayList
黑马程序员Java的个人笔记 BV17F411T7Ao p111~p115 目录 集合存储数据类型的特点 创建对象 ArrayList 成员方法 .add 增加元素 .remove 删除元素 .set 修改元素 .get 查询元素 .size 获取长度 基本数据类型对应的包装类 Character 练习 返回多个数据 集合存储…...
C#怎么判断电脑是否联网
在 C# 中,可以通过几种方法检测计算机是否联网。以下是几种常用的方式: 1. 使用 System.Net.NetworkInformation.Ping 类 通过发送一个 Ping 请求到公共 DNS 服务器(如 Google 的 DNS 8.8.8.8)来检测是否联网。这是最常见的一种…...
软件体系结构复习-02 软件体系结构定位及构建
软件体系结构复习-02 软件体系结构定位及构建 原文链接:《软件体系结构复习-02 软件体系结构定位及构建》 目录 软件体系结构复习-02 软件体系结构定位及构建 1 什么是软件体系结构 2 软件生命周期中的软件体系结构 2.1 生命周期 2.2 定位与作用 1 规划和需求…...
鸿蒙获取 APP 信息及手机信息
前言:获取 APP 版本信息可以通过 bundleManager.getBundleInfoForSelfSync(bundleFlags) 去获取,获取手机信息可以通过 kit.BasicServicesKit 库去获取,以下是封装好的工具类。 import bundleManager from ohos.bundle.bundleManager; impo…...
Linux-V4L2摄像头应用编程
ALPHA/Mini I.MX6U 开发板配套支持多种不同的摄像头,包括正点原子的 ov5640(500W像素)、 ov2640(200W 像素)以及 ov7725(不带 FIFO、30W 像素)这三款摄像头,在开发板出厂系统上&…...
掌握谈判技巧,达成双赢协议
在当今竞争激烈且合作频繁的社会环境中,谈判成为了我们解决分歧、谋求共同发展的重要手段。无论是商业合作、职场交流,还是国际事务协商,掌握谈判技巧以达成双赢协议都具有极其关键的意义。它不仅能够让各方在利益分配上找到平衡点࿰…...
Mysql - 存储引擎
一 MYSQL体系结构简介 MYSQL的体系结构可以分为四个层级,从上往下依次为: 1. 连接层: 最上层为客户端以及一些连接服务,包含连接操作,例如JAVA想要与MYSQL建立连接就需要用到JDBC,PHP语言与Python也可以连接到MYSQL&am…...
借助 CC-Link IE FB 转 Profinet 网关实现西门子 PLC 接入三菱 PLC 系统的解决策略
我们公司自动化生产线上,原有的控制系统采用三菱 PLC 通过 CC-Link IEFB 网络进行通信和控制。后来随着企业生产规模的扩大和对自动化系统集成度要求的提高,需要将部分设备与新引入的西门子 PLC 控制系统相连接,而西门子 PLC 使用 ProfiNet 协…...
未完成_RFdiffusion应用案例_从头设计pMHC的结合剂
目录 1. 论文导读1)摘要2)设计流程3)设计流程的验证 2. 实战 1. 论文导读 Liu, Bingxu, et al. “Design of high specificity binders for peptide-MHC-I complexes.” bioRxiv (2024): 2024-11. 1)摘要 MHC-I 将胞内抗原肽递呈…...
python使用h5py保存数据
python使用h5py保存使用 1、导入库 pip install h5py 2、简介 HDF5(Hierarchical Data Format version 5)是一种可用于存储大量科学数据的文件格式。 支持层次化的数据组织,可以将数据分为多个组(group)和数据集(dataset)。 支持多种数据类型,包括整数、浮点数、字…...
ubuntu24.04利用selenium控制浏览器的方法
ubuntu24.04利用selenium控制浏览器的方法 1.安装selenium sudo apt install python3-selenium2.下载chromedriver 下载地址1 下载地址2 在上面两个地址中挑选自己的版本号 下载chromedriver的时候一定要跟自己浏览器的版本相对应,笔者采用的是版本 131.0.6778.1…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
