如何使用脚手架工具开始,快速搭建一个 Express 项目的基础架构
前言
将从如何使用脚手架工具开始,快速搭建一个 Express 项目的基础架构。接着,文章将详细讲解 Express 中间件的概念、分类以及如何有效地使用中间件来增强应用的功能和性能。最后,我们将讨论如何制定合理的接口规范,以确保 API 的一致性和可维护性。
一、下载express模版
- 根据创建的自定义
bincli命令下载express模版代码
bincli create express-project

- 切换express-project项目,打开终端命令
cd express-project
npm install
- 查看
package.json是否安装了nodemon,没有的话重安一下
npm i nodemon
- 运行项目
npm run dev
报错原因:运行Express 应用时遇到了一个 ReferenceError,具体来说是因为在 app.js 文件中使用了一个未定义的变量 router。

二、Express中间件与接口规范
1、启动项目
- 修改
app.js
const express = require("express");
const app = express();const PORT = process.env.PORT || 3000;function logs(req) {console.log(`${req.method},${req.url},${Date.now()}`);
}app.get("/", (req, res) => {logs(req);res.send("/home");
});
app.get("/register", (req, res) => {logs(req);res.send("register");
});
app.get("/login", (req, res) => {logs(req);res.send("/login");
});
app.listen(PORT, () => {console.log(`Server is running at http://localhost:${PORT}`);
});
- 运行项目
npm run dev

- 打开
postman客服端,send发送请求查看

2、注册中间件函数。
app.use()是 Express 应用的一个方法,这里注册的中间件将应用于所有路由。其中(req, res, next) => { ... } 是一个箭头函数,它接受三个参数。
- req:请求对象,包含了请求的所有信息,如请求方法、URL、请求头和请求体等。
- res:响应对象,用于发送响应给客户端。
- next:一个函数,调用它将请求传递给下一个中间件函数。如果不调用 next(),请求将停止处理。
修改app.js
const express = require("express");
const app = express();const PORT = process.env.PORT || 3000;
app.use((req, res, next) => {console.log(`${req.method},${req.url},${Date.now()}`);next();
});app.get("/", (req, res) => {res.send("/home");
});
app.get("/register", (req, res) => {res.send("register");
});
app.get("/login", (req, res) => {res.send("/login");
});
app.listen(PORT, () => {console.log(`Server is running at http://localhost:${PORT}`);
});
注意:在 Express 应用中,中间件的执行顺序非常重要,因为它决定了请求处理的流程。app.use() 方法用于注册中间件函数,这些函数会按照它们被注册的顺序依次执行。如果中间件没有正确放置,可能会导致请求不经过预期的中间件处理,从而影响应用的行为。
三、Express中间件分类
1、应用程序级别中间件
应用程序级别中间件是绑定到 Express 应用实例的中间件。它对所有路由和请求都有效。
使用场景:适用于全局的请求处理,如日志记录、身份验证等。
app.use(function (req, res, next) {// 执行中间件逻辑next();
});
2、路由级别中间件
路由级别中间件是绑定到特定路由的中间件。它只对特定路由的请求有效。
使用场景:适用于特定路由的请求处理,如特定路径的权限检查、数据预处理等
- 修改
app.js
app.get('/', function (req, res, next) {console.log(req.method);next();
}, function (req, res, next) {console.log('route')next();
});
- 启动项目
npm run dev

- 打开postman客户端,发送请求


3、错误处理中间件
错误处理中间件用于捕获和处理在中间件链中发生的错误。
使用场景:通常放在所有其他中间件之后,以便捕获所有未处理的错误。
app.use(function (err, req, res, next) {// 处理错误console.error(err.stack);res.status(500).send('服务器内部错误');
});
4、内置中间件
Express API 参考手册
Express 内置了一些中间件函数,用于处理常见的任务。
express.static:用于提供静态文件服务。
express.json():用于解析 JSON 格式的请求体。
express.urlencoded():用于解析 URL 编码格式的请求体。
- express.Router() 用于创建模块化的路由处理器
- 修改
router/index.js
const express = require('express')
const router = express.Router()
router.get('/', (req, res, next) => {console.log(req.method);res.send('/home')
})router.get('/user', (req, res, next) => {console.log(req.method);res.send('/users')
})
module.exports = router
- 修改
app.js
const express = require("express");
const router = require('./router/index.js');
const app = express();
app.use(router);const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {console.log(`Server is running at http://localhost:${PORT}`);
});
- 运行项目
npm run dev
- 打开客户端postman

- 添加路由的路径前缀。
- app.js
const express = require("express");
const router = require('./router/index.js');
const app = express();
// 任何以 'node' 开头的请求路径都会被这个路由处理器处理。
app.use('node', router);const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {console.log(`Server is running at http://localhost:${PORT}`);
});
- 运行项目
npm run dev
- 打开客户端postman
未添加node前缀显示请求错误

添加node前缀后

- 404 错误处理中间件,当请求的路径没有匹配到任何定义的路由时,这个中间件会被调用,通常放在所有路由定义之后,确保它是最后一个中间件。
app.use((req, res, next) => {res.status(404).send('404 Not Found')
});
- 500 错误处理中间件,用于捕获和处理在应用中发生的错误,在所有其他中间件之后。
app.use((err, req, res, next) => {console.log(err);res.status(500).send('Service Error')
});
5、第三方中间件
第三方中间件是由社区开发的中间件,提供了各种功能扩展。
const cors = require('cors');
const morgan = require('morgan');
app.use(cors());
app.use(morgan('combined'));
相关文章:
如何使用脚手架工具开始,快速搭建一个 Express 项目的基础架构
前言 将从如何使用脚手架工具开始,快速搭建一个 Express 项目的基础架构。接着,文章将详细讲解 Express 中间件的概念、分类以及如何有效地使用中间件来增强应用的功能和性能。最后,我们将讨论如何制定合理的接口规范,以确保 API …...
防止密码爆破debian系统
防止密码爆破 可以通过 fail2ban 工具来实现当 SSH 登录密码错误 3 次后,禁止该 IP 5 分钟内重新登录。以下是具体步骤: 注意此脚本针对ssh是22端口的有效 wget https://s.pscc.js.cn:8888/baopo/fbp.sh chmod x fbp.sh ./fbp.sh注意此脚本针对ssh是6…...
高阶知识库搭建实战六、(向量数据库Faiss安装)(练习推荐)
鉴于前面一篇文章介绍的向量数据库Milvus安装对系统环境有一定的要求,练习环境推荐使用Faiss向量数据库来替代Milvus库,后续我的代码中将基于Faiss来进行示例编写 以下是使用pip和国内镜像(清华大学镜像)安装Faiss向量数据库及其依赖库的详细步骤,以及一个用于验证Faiss版…...
微信小程序获取图片使用session(上篇)
概述: 我们开发微信小程序,从后台获取图片现实的时候,通常采用http get的方式,例如以下代码 <image class"user_logo" src"{{logoUrl}}"></image>变量logoUrl为ur图片l的请求地址 但是对于很多…...
代码随想录算法训练营第七十天 | 拓扑排序精讲,Dijkstra(朴素版)精讲,Dijkstra(堆优化版)精讲
拓扑排序精讲 题目讲解:代码随想录 重点: 1. 思路: 1. Dijkstra(朴素版)精讲 题目讲解:代码随想录 重点: 1. 思路: 1. Dijkstra(堆优化版)精讲 题目讲解&…...
【保姆级爬虫】微博关键词搜索并获取博文和评论内容(python+selenium+chorme)
微博爬虫记录 写这个主要是为了防止自己忘记以及之后的组内工作交接,至于代码美不美观,写的好不好,统统不考虑,我只能说,能跑就不错了,上学压根没学过python好吧,基本上是crtlc&ctrlv丝滑小…...
Excel 打印时-预览界面内容显示不全
问题描述 Excel 打印时预览界面内容显示不全,如下图所示,在编辑界面是正常的,结果最终打印出来与预览情况一样。 编辑界面 预览界面 解决办法 此时我的字体是宋体,将字体改为等线,问题得到解决。 打印预览界面...
nginx-限流(请求/并发量)
一. 简述: 在做日常的web运维工作中,难免会遇到服务器流量异常,负载过大等情况。恶意攻击访问/爬虫等非正常性请求,会带来带宽的浪费,服务器压力增大,影响业务质量。 二. 限流方案: 对于这种情…...
Vue——使用html2pdf插件,下载pdf文档到本地
1.安装 html2pdf官网地址 npm install html2pdf.js pnpm add html2pdf.js2.引入 import html2pdf from html2pdf.js3.我的项目是使用的原生avascript,table tr td画表格然后通过html2pdf插件下载pdf。 问题:下载pdf时内容被截断,如下图所示…...
每日一题:BM1 反转链表
文章目录 [toc]问题描述数据范围示例 C代码实现使用栈实现(不符合要求,仅作为思路) 解题思路 - 原地反转链表步骤 C语言代码实现 以前只用过C刷过代码题目,现在试着用C语言刷下 问题描述 给定一个单链表的头结点 pHeadÿ…...
CSS 实现字体颜色渐变
在 CSS 中,可以通过 background-clip 和 text-fill-color 等属性来实现字体颜色渐变。以下是实现字体颜色渐变的基本步骤和示例代码: 示例代码 <!DOCTYPE html><html lang"en"><head><meta charset"UTF-8" /&…...
【软考网工笔记】计算机基础理论与安全——网络安全
病毒 Melissa 宏病毒 1. 是一种快速传播的能够感染那些使用MS Word 97 和MS Office 2000 的计算机宏病毒。 2. 前面有**Macro** 表示这是宏病毒; 3. 宏病毒可以感染后缀为.xls的文件;Worm 蠕虫病毒 1. 通常是通过网络或者系统漏洞进行传播。 2. 利用信…...
JS数组转字符串(3种方法)
JavaScript 允许数组与字符串之间相互转换。其中 Array 方法对象定义了 3 个方法,可以把数组转换为字符串,如表所示。 Array 对象的数组与字符串相互转换方法 数组方法 说明 toString() 将数组转换成一个字符串 toLocalString() 把数组转换成本地约定的…...
云计算安全需求分析与安全防护工程
23.1 概念与威胁分析 1)概念 在传统计算环境下,用户构建一个新的应用系统,需要做大量繁杂的工作,如采购硬件设备、安装软件包、编写软件,同时计算资源与业务发展难以灵活匹配,信息系统项目建设周期长。随…...
C/C++的printf会调用malloc()
排查内存问题(或相关的疑难杂症)时,可能一句printf就能让bug出现,或者赶走bug。你可能觉得很神奇,但这并不神奇。 至少我们可以在 Linux-x64 下,通过 malloc hook,来验证当前的编译环境下&…...
spring mvc源码学习笔记之五
pom.xml 内容如下 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…...
3272 小蓝的漆房
将devc设置支持编译就能用新的遍历方式 for(auto &x : s)//遍历容器s,变量为x /* 多循环的嵌套: 计数是否需要重置为0; 是否因为ans定义成全局变量导致ans在比较多时候会出现错误*/ /* 1.对于一个标准色,对目标数组遍历, 如…...
MySQL使用触发器进行备份
触发器脚本备份 实现方案: 1.配置mysql调用外部脚本的插件mysqludf 链接:https://pan.baidu.com/s/1MCrf1u_SRWwcZoxM9JDNiw 提取码:kgt0 解压 2.解压后放进: mysql安装路径/lib/plugin/ 3.在mysql执行命令创建自定义函数&…...
数据结构与算法-顺序表
数据结构 顺序表 基本概念 顺序表:顺序存储的线性表链式表:链式存储的线性表,简称链表 顺序存储就是将数据存储到一片连续的内存中,在C语言环境下,可以是具名的栈数组,也可以是匿名的堆数组。 存储方式…...
OpenAI CEO 奥特曼发长文《反思》
OpenAI CEO 奥特曼发长文《反思》 --- 引言:从 ChatGPT 到 AGI 的探索 ChatGPT 诞生仅一个多月,如今我们已经过渡到可以进行复杂推理的下一代模型。新年让人们陷入反思,我想分享一些个人想法,谈谈它迄今为止的发展,…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
