Express框架入门:从基础搭建到路由系统详解
1. Express基础环境搭建与服务器创建作为Node.js最流行的Web框架之一Express让服务器开发变得异常简单。我们先从最基础的服务器搭建开始1.1 项目初始化与Express安装首先创建一个空目录作为项目根目录执行npm初始化命令mkdir express-demo cd express-demo npm init -y接着安装Express核心包npm install express --save提示使用--save参数会将依赖自动写入package.json这是现代Node.js项目的标准做法。如果是老版本npm(5.0之前)需要显式添加这个参数。1.2 创建基础服务器新建server.js作为入口文件写入以下代码const express require(express); const app express(); app.get(/, (req, res) { res.send(欢迎来到Express世界); }); app.listen(3000, () { console.log(服务器已启动访问地址http://localhost:3000); });这个最简单的Express服务器已经可以处理GET请求。相比原生Node.js的http模块Express用几行代码就实现了路由功能。1.3 开发工具配置为了提高开发效率建议安装nodemon工具npm install -g nodemon然后使用nodemon启动服务器nodemon server.jsnodemon会监控文件变化自动重启服务这在开发阶段非常实用。如果入口文件不是server.js而是app.js则需指定文件名nodemon app.js2. Express路由系统深度解析2.1 基础路由配置Express的路由定义非常直观基本语法是app.METHOD(PATH, HANDLER)其中METHOD可以是get/post/put/delete等HTTP方法PATH是URL路径HANDLER是处理函数示例app.get(/api/users, (req, res) { res.json([{id: 1, name: 张三}, {id: 2, name: 李四}]); });2.2 动态路由参数路由可以包含动态参数通过req.params获取app.get(/users/:userId/posts/:postId, (req, res) { console.log(req.params); // { userId: 123, postId: 456 } res.send(用户${req.params.userId}的文章${req.params.postId}); });2.3 路由正则匹配Express路由支持正则表达式提供更灵活的匹配方式// 匹配/acd或/abcd app.get(/ab?cd, (req, res) { res.send(匹配成功); }); // 匹配/1xx2其中x可以是任意字符 app.get(/1.*2, (req, res) { res.send(通配符匹配); });2.4 查询字符串处理对于URL中的查询参数(?keyvalue)Express自动解析并存入req.queryapp.get(/search, (req, res) { // 访问/search?qexpresspage2 console.log(req.query); // { q: express, page: 2 } res.send(搜索关键词${req.query.q}第${req.query.page}页); });3. 请求处理与数据获取3.1 GET请求处理GET请求是最常见的HTTP方法Express已经内置支持app.get(/products, (req, res) { const products [ {id: 1, name: 手机, price: 3999}, {id: 2, name: 笔记本, price: 5999} ]; res.json(products); });3.2 POST请求与body-parser处理POST请求需要body-parser中间件来解析请求体npm install body-parser --save使用示例const bodyParser require(body-parser); // 解析application/x-www-form-urlencoded app.use(bodyParser.urlencoded({ extended: false })); // 解析application/json app.use(bodyParser.json()); app.post(/login, (req, res) { console.log(req.body); // 获取POST数据 res.send(欢迎${req.body.username}); });注意extended: false表示使用querystring库解析URL编码数据true表示使用qs库。对于简单数据false即可。3.3 不同内容类型的处理可以为不同路由指定不同的解析器const jsonParser bodyParser.json(); const urlencodedParser bodyParser.urlencoded({ extended: false }); // 只处理JSON数据 app.post(/api/users, jsonParser, (req, res) { // ... }); // 只处理表单数据 app.post(/contact, urlencodedParser, (req, res) { // ... });4. 文件上传与multer中间件4.1 multer基础配置处理文件上传需要multer中间件npm install multer --save基本使用const multer require(multer); const upload multer({ dest: uploads/ }); app.post(/upload, upload.single(avatar), (req, res) { console.log(req.file); // 上传文件信息 res.send(上传成功); });对应的HTML表单form action/upload methodpost enctypemultipart/form-data input typefile nameavatar button typesubmit上传/button /form4.2 自定义存储配置multer允许自定义文件名和存储路径const storage multer.diskStorage({ destination: (req, file, cb) { cb(null, uploads/); }, filename: (req, file, cb) { const uniqueSuffix Date.now() - Math.round(Math.random() * 1E9); cb(null, file.fieldname - uniqueSuffix path.extname(file.originalname)); } }); const upload multer({ storage: storage });4.3 文件过滤与限制可以添加文件类型和大小限制const fileFilter (req, file, cb) { if (file.mimetype image/jpeg || file.mimetype image/png) { cb(null, true); } else { cb(new Error(只支持JPEG/PNG格式), false); } }; const upload multer({ storage: storage, limits: { fileSize: 1024 * 1024 * 5 // 限制5MB }, fileFilter: fileFilter });5. EJS模板引擎实战5.1 EJS基础配置安装EJS模板引擎npm install ejs --save配置Express使用EJSapp.set(views, path.join(__dirname, views)); app.set(view engine, ejs);5.2 基本模板渲染创建views/index.ejs!DOCTYPE html html head title% title %/title /head body h1% message %/h1 /body /html路由中渲染模板app.get(/, (req, res) { res.render(index, { title: Express首页, message: 欢迎使用EJS模板引擎 }); });5.3 模板逻辑控制EJS支持JavaScript逻辑% if (user) { % h2欢迎, % user.name %/h2 % } else { % a href/login请登录/a % } % ul % items.forEach(item { % li% item %/li % }) % /ul5.4 模板布局与包含创建公共头部views/partials/header.ejsheader nav a href/首页/a a href/about关于/a /nav /header在其他模板中包含%- include(partials/header) % main !-- 页面主要内容 -- /main6. 项目优化与最佳实践6.1 路由模块化将路由拆分到单独文件routes/users.jsconst express require(express); const router express.Router(); router.get(/, (req, res) { res.send(用户列表); }); router.get(/:id, (req, res) { res.send(用户详情${req.params.id}); }); module.exports router;主文件中引入const userRoutes require(./routes/users); app.use(/users, userRoutes);6.2 错误处理中间件自定义错误处理// 404处理 app.use((req, res, next) { res.status(404).render(404); }); // 错误处理 app.use((err, req, res, next) { console.error(err.stack); res.status(500).render(500); });6.3 安全最佳实践重要安全措施const helmet require(helmet); app.use(helmet()); // 防止跨站请求伪造 const csrf require(csurf); app.use(csrf({ cookie: true })); // 限流保护 const rateLimit require(express-rate-limit); const limiter rateLimit({ windowMs: 15 * 60 * 1000, // 15分钟 max: 100 // 每个IP限制100次请求 }); app.use(limiter);6.4 性能优化技巧提升Express性能的方法// 启用gzip压缩 const compression require(compression); app.use(compression()); // 静态文件缓存 app.use(express.static(public, { maxAge: 1y, immutable: true })); // 集群模式 const cluster require(cluster); const numCPUs require(os).cpus().length; if (cluster.isMaster) { for (let i 0; i numCPUs; i) { cluster.fork(); } } else { // 启动Express应用 }7. 常见问题与解决方案7.1 跨域问题处理使用cors中间件解决跨域npm install cors --save配置示例const cors require(cors); // 允许所有来源 app.use(cors()); // 自定义配置 app.use(cors({ origin: https://example.com, methods: [GET, POST], allowedHeaders: [Content-Type] }));7.2 静态文件服务托管静态文件目录app.use(express.static(public)); // 可以添加多个静态目录 app.use(/uploads, express.static(uploads));7.3 会话管理使用express-session管理会话npm install express-session --save基本配置const session require(express-session); app.use(session({ secret: your-secret-key, resave: false, saveUninitialized: true, cookie: { secure: true } }));7.4 数据库集成连接MongoDB示例const mongoose require(mongoose); mongoose.connect(mongodb://localhost:27017/express-demo, { useNewUrlParser: true, useUnifiedTopology: true }); const User mongoose.model(User, { name: String, email: String }); app.post(/users, async (req, res) { const user new User(req.body); await user.save(); res.status(201).send(user); });8. 项目部署与生产环境配置8.1 环境变量管理使用dotenv管理环境变量npm install dotenv --save创建.env文件PORT3000 DB_URLmongodb://localhost:27017/prod-db SECRET_KEYyour-production-secret应用配置require(dotenv).config(); const port process.env.PORT || 3000; app.listen(port, () { console.log(服务器运行在${port}端口); });8.2 PM2进程管理使用PM2部署Node.js应用npm install pm2 -g pm2 start server.js --name express-app常用PM2命令pm2 list # 查看进程列表 pm2 logs # 查看日志 pm2 restart all # 重启所有应用 pm2 delete all # 删除所有应用8.3 Nginx反向代理配置Nginx作为反向代理server { listen 80; server_name example.com; location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }8.4 HTTPS配置使用Lets Encrypt免费SSL证书sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d example.comExpress中强制HTTPSapp.use((req, res, next) { if (!req.secure req.get(X-Forwarded-Proto) ! https process.env.NODE_ENV production) { return res.redirect(https:// req.get(Host) req.url); } next(); });在实际项目中Express的灵活性和丰富的中间件生态系统使其成为Node.js Web开发的首选框架。通过合理组织代码结构、选择适当的中间件和遵循最佳实践可以构建出高性能、易维护的Web应用。

相关新闻

对比口服司美格鲁肽,奥氟格列隆Orforglipron的减重数据副作用全梳理【海得康】

对比口服司美格鲁肽,奥氟格列隆Orforglipron的减重数据副作用全梳理【海得康】

随着口服GLP-1赛道的产品不断落地,不少代谢病患者开始在司美格鲁肽口服版和奥氟格列隆Orforglipron之间做选择,两款药物同属每日口服的GLP-1受体激动剂,却在分子机制、临床数据、用药体验上存在显著差异。本文基于公开的权威Ⅲ期临床试验结果…

2026/10/15 9:01:39 阅读更多 →
GPMC接口与NAND闪存:硬件ECC与流模式访问实战解析

GPMC接口与NAND闪存:硬件ECC与流模式访问实战解析

1. GPMC接口与NAND闪存:嵌入式存储系统的基石在嵌入式系统开发,尤其是工业控制、汽车电子或高端消费电子领域,微控制器与外部存储器的交互效率直接决定了系统的整体性能。当项目需要处理大量日志、存储固件镜像或运行复杂的文件系统时&#x…

2026/10/15 17:16:27 阅读更多 →
DynaMiCS:大语言模型动态混合微调框架的原理与实践

DynaMiCS:大语言模型动态混合微调框架的原理与实践

在实际的大语言模型(LLM)应用开发中,我们经常面临一个核心矛盾:一方面希望模型能够通过微调适配特定业务场景,另一方面又受限于计算资源、推理延迟或部署成本。传统的全参数微调(Full Fine-Tuning&#xff…

2026/10/15 17:16:24 阅读更多 →

最新新闻

Ubuntu下检测鼠标键盘活动状态:从事件读取到长期稳定运行

Ubuntu下检测鼠标键盘活动状态:从事件读取到长期稳定运行

1. 为什么要在 Ubuntu 上盯住鼠标键盘的"沉默"很多人第一次听到"检测鼠标键盘是否活动"这个需求,第一反应是:这有什么难的,插上不就能用吗?但真正在 Ubuntu 上做过长期运行设备、无人值守终端、公共展示机或者…

2026/10/16 3:45:08 阅读更多 →
从布片到原创布艺玩偶:沙耶的doll手作全流程教程

从布片到原创布艺玩偶:沙耶的doll手作全流程教程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:45:08 阅读更多 →
xcom2-launcher(AML):XCOM 2 与奇美拉小队的替代性 Mod 启动器完整指南

xcom2-launcher(AML):XCOM 2 与奇美拉小队的替代性 Mod 启动器完整指南

桌面应用游戏开发 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-launcher 点击查看 免费下载 …

2026/10/16 3:45:08 阅读更多 →
LangChain实战:系统提示词、工具封装与记忆体构建Agent应用

LangChain实战:系统提示词、工具封装与记忆体构建Agent应用

要说LangChain的入门教程,网上确实不少,但大部分都停留在“调一个模型、问一句话”的阶段。真正做应用的时候,光会调模型远远不够——系统怎么设计、上下文怎么传、工具怎么让模型调用、返回格式怎么固定、多轮对话怎么记住之前说过什么&…

2026/10/16 3:45:08 阅读更多 →
压缩机PLC程序实战:恒压PID与防喘振保护框架详解

压缩机PLC程序实战:恒压PID与防喘振保护框架详解

简介:一套面向空调压缩机控制的PLC程序及其VC上位机监控软件完整工程,适用于工业自动化学习者、PLC工程师及C上位机开发人员。程序逻辑负责采集与判断压缩机运行参数,上位机通过串口或以太网与PLC通信,直观显示状态并支持告警&…

2026/10/16 3:45:08 阅读更多 →
基于改进灵敏度分析的有源配电网智能软开关优化配置仿真

基于改进灵敏度分析的有源配电网智能软开关优化配置仿真

说实话,看到“基于改进灵敏度分析的有源配电网智能软开关优化配置”这个选题时,我第一反应是持保留态度的。“改进”这个词近年来被用得太多,很多工作说白了就是把参数换成另一个名字再做一遍,实质增益不大。直到我真的在IEEE33节…

2026/10/16 3:44:08 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →