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…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
