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…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
C# winform教程(二)----checkbox
一、作用 提供一个用户选择或者不选的状态,这是一个可以多选的控件。 二、属性 其实功能大差不差,除了特殊的几个外,与button基本相同,所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...
SQL进阶之旅 Day 22:批处理与游标优化
【SQL进阶之旅 Day 22】批处理与游标优化 文章简述(300字左右) 在数据库开发中,面对大量数据的处理任务时,单条SQL语句往往无法满足性能需求。本篇文章聚焦“批处理与游标优化”,深入探讨如何通过批量操作和游标技术提…...
ZYNQ学习记录FPGA(二)Verilog语言
一、Verilog简介 1.1 HDL(Hardware Description language) 在解释HDL之前,先来了解一下数字系统设计的流程:逻辑设计 -> 电路实现 -> 系统验证。 逻辑设计又称前端,在这个过程中就需要用到HDL,正文…...
【笔记】AI Agent 项目 SUNA 部署 之 Docker 构建记录
#工作记录 构建过程记录 Microsoft Windows [Version 10.0.27871.1000] (c) Microsoft Corporation. All rights reserved.(suna-py3.12) F:\PythonProjects\suna>python setup.py --admin███████╗██╗ ██╗███╗ ██╗ █████╗ ██╔════╝…...
用 FFmpeg 实现 RTMP 推流直播
RTMP(Real-Time Messaging Protocol) 是直播行业中常用的传输协议。 一般来说,直播服务商会给你: ✅ 一个 RTMP 推流地址(你推视频上去) ✅ 一个 HLS 或 FLV 拉流地址(观众观看用)…...
SpringCloud优势
目录 完善的微服务支持 高可用性和容错性 灵活的配置管理 强大的服务网关 分布式追踪能力 丰富的社区生态 易于与其他技术栈集成 完善的微服务支持 Spring Cloud 提供了一整套工具和组件来支持微服务架构的开发,包括服务注册与发现、负载均衡、断路器、配置管理等功能…...
