Express框架入门:从基础搭建到路由系统详解

📅 2026/7/20 21:50:10 👁️ 阅读次数 📝 编程学习
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.js

nodemon会监控文件变化自动重启服务,这在开发阶段非常实用。如果入口文件不是server.js而是app.js,则需指定文件名:

nodemon app.js

2. 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中的查询参数(?key=value),Express自动解析并存入req.query:

app.get('/search', (req, res) => { // 访问/search?q=express&page=2 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" method="post" enctype="multipart/form-data"> <input type="file" name="avatar"> <button type="submit">上传</button> </form>

4.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使用EJS:

app.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> <% }) %> </ul>

5.4 模板布局与包含

创建公共头部views/partials/header.ejs:

<header> <nav> <a href="/">首页</a> <a href="/about">关于</a> </nav> </header>

在其他模板中包含:

<%- include('partials/header') %> <main> <!-- 页面主要内容 --> </main>

6. 项目优化与最佳实践

6.1 路由模块化

将路由拆分到单独文件routes/users.js:

const 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文件:

PORT=3000 DB_URL=mongodb://localhost:27017/prod-db SECRET_KEY=your-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配置

使用Let's Encrypt免费SSL证书:

sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d example.com

Express中强制HTTPS:

app.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应用。