详细介绍:Node.js中Express框架入门教程
2025-09-20 16:38 tlnshuju 阅读(0) 评论(0) 收藏 举报什么是Express.js?
Express.js是Node.js最受欢迎的Web应用框架之一,被称为"快速、开放、极简的Web框架"。它为构建Web应用程序和API提供了一套丰富的功能,同时保持了轻量级和灵活性。
为什么选择Express?
- 简单易学:API简洁明了,学习曲线平缓
- 灵活性强:不强制特定的项目结构,开发者可以自由组织代码
- 中间件丰富:拥有庞大的中间件生态系统
- 性能优秀:轻量级设计,运行效率高
- 社区活跃:文档完善,社区支持强大
环境准备
在开始之前,确保您的系统已安装:
- Node.js(版本12或更高)
- npm(通常随Node.js一起安装)
检查安装版本:
node --version
npm --version
安装Express
创建新项目
# 创建项目目录
mkdir my-express-app
cd my-express-app
# 初始化npm项目
npm init -y
# 安装Express
npm install express
使用Express生成器(可选)
# 全局安装Express生成器
npm install -g express-generator
# 创建项目
express --view=ejs my-app
cd my-app
npm install
创建第一个Express应用
让我们创建一个简单的"Hello World"应用:
基础示例
// app.js
const express = require('express');
const app = express();
const port = 3000;
// 定义路由
app.get('/', (req, res) => {
res.send('Hello World!');
});
// 启动服务器
app.listen(port, () => {
console.log(`服务器运行在 http://localhost:${port}`);
});
运行应用:
node app.js
访问 http://localhost:3000
,您将看到"Hello World!"消息。
路由基础
路由决定了应用程序如何响应客户端对特定端点的请求。
HTTP方法
// GET请求
app.get('/users', (req, res) => {
res.send('获取用户列表');
});
// POST请求
app.post('/users', (req, res) => {
res.send('创建新用户');
});
// PUT请求
app.put('/users/:id', (req, res) => {
res.send(`更新用户 ${req.params.id}`);
});
// DELETE请求
app.delete('/users/:id', (req, res) => {
res.send(`删除用户 ${req.params.id}`);
});
路由参数
// 路径参数
app.get('/users/:id', (req, res) => {
const userId = req.params.id;
res.send(`用户ID: ${userId}`);
});
// 多个参数
app.get('/users/:userId/posts/:postId', (req, res) => {
const { userId, postId } = req.params;
res.json({ userId, postId });
});
// 查询参数
app.get('/search', (req, res) => {
const { q, page, limit } = req.query;
res.json({ query: q, page, limit });
});
路由模式匹配
// 通配符
app.get('/ab*cd', (req, res) => {
res.send('匹配 abcd, abxcd, abRANDOMcd 等');
});
// 可选参数
app.get('/products/:id?', (req, res) => {
if (req.params.id) {
res.send(`产品ID: ${req.params.id}`);
} else {
res.send('所有产品');
}
});
中间件详解
中间件是Express的核心概念,它是在请求-响应循环中执行的函数。
应用级中间件
// 全局中间件
app.use((req, res, next) => {
console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`);
next(); // 调用next()继续执行下一个中间件
});
// 特定路径的中间件
app.use('/api', (req, res, next) => {
console.log('API请求');
next();
});
内置中间件
// 解析JSON请求体
app.use(express.json());
// 解析URL编码的请求体
app.use(express.urlencoded({ extended: true }));
// 提供静态文件服务
app.use(express.static('public'));
第三方中间件
# 安装常用中间件
npm install morgan cors helmet compression
const morgan = require('morgan');
const cors = require('cors');
const helmet = require('helmet');
const compression = require('compression');
// 日志中间件
app.use(morgan('combined'));
// 启用CORS
app.use(cors());
// 安全中间件
app.use(helmet());
// 压缩响应
app.use(compression());
错误处理中间件
// 错误处理中间件必须有四个参数
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({
error: '服务器内部错误',
message: err.message
});
});
模板引擎
Express支持多种模板引擎,如EJS、Pug、Handlebars等。
使用EJS
npm install ejs
// 设置模板引擎
app.set('view engine', 'ejs');
app.set('views', './views');
// 渲染模板
app.get('/profile/:name', (req, res) => {
res.render('profile', {
username: req.params.name,
title: '用户资料'
});
});
创建模板文件 views/profile.ejs
:
欢迎, !
这是您的个人资料页面。
完整示例:简单的博客API
const express = require('express');
const app = express();
const port = 3000;
// 中间件
app.use(express.json());
app.use(express.static('public'));
// 模拟数据
let posts = [
{ id: 1, title: '第一篇文章', content: '这是第一篇文章的内容' },
{ id: 2, title: '第二篇文章', content: '这是第二篇文章的内容' }
];
// 获取所有文章
app.get('/api/posts', (req, res) => {
res.json(posts);
});
// 获取特定文章
app.get('/api/posts/:id', (req, res) => {
const post = posts.find(p => p.id === parseInt(req.params.id));
if (!post) {
return res.status(404).json({ error: '文章未找到' });
}
res.json(post);
});
// 创建新文章
app.post('/api/posts', (req, res) => {
const { title, content } = req.body;
if (!title || !content) {
return res.status(400).json({ error: '标题和内容不能为空' });
}
const newPost = {
id: posts.length + 1,
title,
content
};
posts.push(newPost);
res.status(201).json(newPost);
});
// 更新文章
app.put('/api/posts/:id', (req, res) => {
const postIndex = posts.findIndex(p => p.id === parseInt(req.params.id));
if (postIndex === -1) {
return res.status(404).json({ error: '文章未找到' });
}
const { title, content } = req.body;
posts[postIndex] = { ...posts[postIndex], title, content };
res.json(posts[postIndex]);
});
// 删除文章
app.delete('/api/posts/:id', (req, res) => {
const postIndex = posts.findIndex(p => p.id === parseInt(req.params.id));
if (postIndex === -1) {
return res.status(404).json({ error: '文章未找到' });
}
posts.splice(postIndex, 1);
res.status(204).send();
});
// 错误处理
app.use((req, res) => {
res.status(404).json({ error: '页面未找到' });
});
app.listen(port, () => {
console.log(`博客API运行在 http://localhost:${port}`);
});
最佳实践
项目结构建议
my-app/
├── public/ # 静态文件
├── views/ # 模板文件
├── routes/ # 路由模块
├── middleware/ # 自定义中间件
├── models/ # 数据模型
├── controllers/ # 控制器
├── config/ # 配置文件
├── app.js # 主应用文件
└── package.json
路由模块化
// routes/users.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.send('用户列表');
});
router.get('/:id', (req, res) => {
res.send(`用户ID: ${req.params.id}`);
});
module.exports = router;
// 在主应用中使用
const userRoutes = require('./routes/users');
app.use('/users', userRoutes);
环境配置
// 使用环境变量
const port = process.env.PORT || 3000;
const env = process.env.NODE_ENV || 'development';
if (env === 'development') {
app.use(morgan('dev'));
}
下一步学习
掌握了Express基础后,您可以继续学习:
- 数据库集成:MongoDB (Mongoose)、MySQL (Sequelize)
- 身份验证:JWT、Passport.js
- API文档:Swagger/OpenAPI
- 测试:Jest、Supertest
- 部署:Docker、Heroku、AWS
总结
Express.js是一个功能强大而又简洁的Web框架,非常适合快速构建Web应用程序和API。通过掌握路由、中间件、模板引擎等核心概念,您就能够开发出功能丰富的Web应用。
记住Express的哲学:保持简单,但提供足够的灵活性让开发者能够构建复杂的应用程序。随着经验的积累,您将能够利用Express的强大功能构建更加复杂和优雅的Web解决方案。
相关资源
- Express.js官方文档
- Node.js官方文档
- MDN Web文档
- Express.js GitHub仓库
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/908434.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!相关文章
实用指南:【鸿蒙面试题-6】LazyForEach 懒加载
实用指南:【鸿蒙面试题-6】LazyForEach 懒加载pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &…
基于LlamaIndex的相似性搜索
🌟 引言:为什么需要“相似性搜索”?
在信息爆炸的时代,我们每天面对大量文档、笔记、技术手册、会议记录……如何快速从自己的“知识库”中找到最相关的内容?
传统关键词搜索(如 Ctrl+F)已经不够用了 —— 它无…
第二周预习报告(AI)
AI对学习内容的总结
使用AI工具: 腾讯元宝 (https://yuanbao.tencent.com/)
总结内容:
本周学习聚焦于C语言高级特性、对称密码算法实现及密码学编码格式。
Head First C第8章:静态与动态库核心思想: 代码复用与模…
编写代码时遇到的checkstyle问题归纳
当开发者编写代码时,遵循一定的代码风格和规范是必要的,这不仅有助于提高代码质量,也使代码更易于阅读和维护。Checkstyle 是一个用于检查Java源代码的工具,它帮助开发者按照一定的编码标准进行编程。它可以集成在…
.netcore的Lucene.Net基础应用
.netcore的Lucene.Net基础应用最近研究了一下使用.netcore的Lucene.Net应用,整理一下研究内容。
一、研究原因
1、系统环境:多终端、多服务、达梦数据库8、.netcore7.0、多机负载。
2、业务数量:单表1000万条数据,…
rook-ceph CRD资源配置时效困难
rook-ceph CRD资源配置时效困难2025-09-20 16:05
tlnshuju
阅读(0)
评论(0) 收藏
举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !importa…
实用指南:conda常见问题
pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …
关于1200模拟量输入滤波的问题
参考:为什么使用S7-1200模拟量输入模块时接收到变动很大的不稳定的值?unstable
参考:关于模拟量输入滤波的问题-SIMATIC S7-1500系列-找答案-西门子中国滤波周期设置和模拟量输入反馈速率有关!!!
调整为无时,可…
在Ubuntu 16.04上安装openjdk-6/7/8-jdk的步骤
由于Ubuntu 16.04的标准库可能不包含更早版本的OpenJDK,你可能需要添加额外的存储库或者下载特定的安装包。对于OpenJDK的这些旧版本,你可以使用Third-party PPA(个人软件包归档),或者从OpenJDK档案站点下载相应的…
物流行业信息咨询智能问答系统
物流行业信息咨询智能问答系统2025-09-20 15:58
dribs
阅读(0)
评论(0) 收藏
举报背景
练手rag项目
LLM都是基于过去的经验数据进行训练完成;无法处理获取实时的信息,需结合RAG实现;处理私域的数据
流程原理项目…
插座(SOCKET)
程序用来“上网说话”的工具。1:什么是套接字?
应用程序与网络协议栈之间进行数据收发的编程接口(API)
2.如何理解?
应用程序需要套接字才能接入网络,与其他计算机上的程序进行通信(插座---->电器需要插入插…
线性代数 行列式 | 子式 / 主子式 / 顺序主子式 / 余子式 / 代数余子式 - 教程
pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …
Red Hat 8.5.0-18 部署ceph文件系统 - 实践
pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …
kettle从入门到精通 第108课 ETL之kettle 国产麒麟系统安装kettle教程
场景:最近vip群小伙伴在国产麒麟系统安装kettle时遇到无法正常启动的问题,今天周末远程连麦小伙伴一起解决此问题,梳理成章,方便后续小伙伴。 1、报错信息
国产麒麟系统安装kettle时遇到无法正常启动,提示错误信息…
部署 Squid 代理服务
安装 Squid:
sudo apt install squid编辑配置文件:
sudoedit /etc/squid/squid.confhttp_port 3128启动 Squid 服务
sudo systemctl start squid
sudo systemctl enable squid
k8s--etcd - 详解
k8s--etcd - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Cou…
HBase 的自带命令行工具 hbase shell 的基本使用
1. 进入 HBase Shell
首先,通过以下命令连接到您的 HBase 集群命令行界面:
hbase shell
连接成功后,提示符会变为 hbase(main):001:0>,表示您已经可以在里面执行 HBase 专属命令了。
2. 查看集群状态和表列表(…
市场交易反心理特征之一:太过完美而不敢买入
市场交易的最大特点就是“反心理”性。经常盘后看起来非常简单的事情,在盘前、盘中都会变得莫名复杂。明明盘前根据自己的交易策略可以轻松选出的牛股,开盘后没买,买了另一个,结果牛股涨停,买的票要么下跌,要么不…
3peak DCDC转换芯片选型列表
Part Number
Subcategory
VIN (V)
Output (V)
Max Output Current (A)
PackageTPE15017
以太网供电
24~57
/
/
QFN3X4-19TPM1525
功率级DrMOS
7~140
/
1
SOP8TPM6501
隔离电源
2.5~25
/
1
SOT23-5TPM6501Q
隔离电源
2.…
重塑公司绩效管理的 6 种方法
有远见的公司开始了解绩效管理的真正潜力。通过将传统绩效管理转变为持续绩效管理——建立在定期签到、持续反馈和认可时刻的基础上——公司可以通过让员工发挥最大潜力来优化绩效。
1、通过真实和积极的文化建立信任基…