Node.js后端框架Express.js
1. 什么是 Express.js?
Express.js 是一个最小且灵活的 Node.js Web 应用框架,为构建 Web 和移动应用提供了一系列强大的特性。
# 创建 Express 项目 mkdir my-express-app cd my-express-app npm init -y npm install express
2. 核心特性
主要特点
极简且无约束
中间件架构
路由系统强大
模板引擎支持
错误处理机制
高性能
3. 基础应用结构
最小应用示例
// 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}`)
})标准项目结构
my-express-app/ ├── src/ │ ├── app.js # 应用入口 │ ├── routes/ # 路由文件 │ │ ├── index.js │ │ ├── users.js │ │ └── api.js │ ├── controllers/ # 控制器 │ ├── models/ # 数据模型 │ ├── middleware/ # 中间件 │ ├── public/ # 静态文件 │ ├── views/ # 模板文件 │ └── utils/ # 工具函数 ├── package.json └── .env
4. 应用对象 (Application)
创建 Express 应用
const express = require('express')
const app = express()// 应用配置
app.set('view engine', 'ejs') // 模板引擎
app.set('views', './views') // 模板目录
app.set('port', process.env.PORT || 3000) // 端口设置常用应用方法
// 静态文件服务
app.use(express.static('public'))// 解析请求体
app.use(express.json()) // JSON 解析
app.use(express.urlencoded({ extended: true })) // URL编码解析// 设置环境变量
app.set('env', 'production')5. 路由系统 (Routing)
基础路由
// GET 请求
app.get('/users', (req, res) => {res.send('获取用户列表')
})// POST 请求
app.post('/users', (req, res) => {const userData = req.bodyres.json({ message: '用户创建成功', data: userData })
})// PUT 请求
app.put('/users/:id', (req, res) => {const userId = req.params.idres.send(`更新用户 ${userId}`)
})// DELETE 请求
app.delete('/users/:id', (req, res) => {const userId = req.params.idres.send(`删除用户 ${userId}`)
})路由参数
// 路径参数
app.get('/users/:userId/books/:bookId', (req, res) => {res.json({userId: req.params.userId,bookId: req.params.bookId})
})// 查询参数
app.get('/search', (req, res) => {const { q, page = 1 } = req.queryres.json({ query: q, page: parseInt(page) })
})路由模块化
// routes/users.js
const express = require('express')
const router = express.Router()// GET /users
router.get('/', (req, res) => {res.send('用户列表')
})// POST /users
router.post('/', (req, res) => {res.send('创建用户')
})// GET /users/:id
router.get('/:id', (req, res) => {res.send(`用户详情: ${req.params.id}`)
})module.exports = router在主应用中挂载路由
// app.js
const userRoutes = require('./routes/users')
const apiRoutes = require('./routes/api')app.use('/users', userRoutes)
app.use('/api', apiRoutes)6. 中间件 (Middleware)
自定义中间件
// 日志中间件
app.use((req, res, next) => {console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`)next()
})// 认证中间件
const authMiddleware = (req, res, next) => {const token = req.headers.authorizationif (!token) {return res.status(401).json({ error: '未提供认证令牌' })}// 验证 token...next()
}// 使用中间件
app.use('/api/protected', authMiddleware)错误处理中间件
// 404 处理
app.use((req, res, next) => {res.status(404).json({ error: '路由不存在' })
})// 全局错误处理
app.use((err, req, res, next) => {console.error(err.stack)res.status(500).json({ error: '服务器内部错误',message: process.env.NODE_ENV === 'development' ? err.message : undefined})
})7. 请求和响应对象
请求对象 (Request)
app.post('/users', (req, res) => {// 请求体数据console.log(req.body)// 查询参数console.log(req.query)// 路径参数console.log(req.params)// 请求头console.log(req.headers)// Cookiesconsole.log(req.cookies)// 文件上传console.log(req.files)
})响应对象 (Response)
app.get('/api/data', (req, res) => {// 发送 JSONres.json({ message: 'Hello' })// 发送状态码 + JSONres.status(201).json({ id: 1, name: 'John' })// 设置响应头res.set('Content-Type', 'application/json')// 重定向res.redirect('/new-path')// 下载文件res.download('/path/to/file.pdf')// 渲染模板res.render('index', { title: '首页' })
})8. 模板引擎
配置 EJS 模板
// 设置 EJS
app.set('view engine', 'ejs')
app.set('views', './views')// 渲染模板
app.get('/', (req, res) => {res.render('index', {title: '我的网站',users: ['张三', '李四', '王五']})
})EJS 模板示例
<!-- views/index.ejs -->
<!DOCTYPE html>
<html>
<head><title><%= title %></title>
</head>
<body><h1>欢迎来到 <%= title %></h1><ul><% users.forEach(user => { %><li><%= user %></li><% }) %></ul>
</body>
</html>9. 静态文件服务
// 提供静态文件
app.use(express.static('public'))// 多个静态目录
app.use(express.static('public'))
app.use(express.static('uploads'))// 虚拟路径前缀
app.use('/static', express.static('public'))10. 错误处理
同步错误处理
app.get('/error', (req, res) => {throw new Error('测试错误')
})异步错误处理
app.get('/async-error', async (req, res, next) => {try {const data = await someAsyncOperation()res.json(data)} catch (error) {next(error)}
})自定义错误类
class AppError extends Error {constructor(message, statusCode) {super(message)this.statusCode = statusCodethis.isOperational = trueError.captureStackTrace(this, this.constructor)}
}// 使用自定义错误
app.get('/protected', (req, res, next) => {if (!req.user) {return next(new AppError('请先登录', 401))}res.send('受保护的内容')
})11. 数据库集成
MongoDB + Mongoose
const mongoose = require('mongoose')// 连接数据库
mongoose.connect('mongodb://localhost:27017/myapp')// 定义模型
const UserSchema = new mongoose.Schema({name: String,email: String,age: Number
})const User = mongoose.model('User', UserSchema)// 在路由中使用
app.get('/api/users', async (req, res) => {try {const users = await User.find()res.json(users)} catch (error) {res.status(500).json({ error: error.message })}
})MySQL + mysql2
const mysql = require('mysql2/promise')// 创建连接池
const pool = mysql.createPool({host: 'localhost',user: 'root',password: 'password',database: 'myapp',waitForConnections: true,connectionLimit: 10,queueLimit: 0
})// 在路由中使用
app.get('/api/products', async (req, res) => {try {const [rows] = await pool.execute('SELECT * FROM products')res.json(rows)} catch (error) {res.status(500).json({ error: error.message })}
})12. 安全最佳实践
安全中间件
const helmet = require('helmet')
const rateLimit = require('express-rate-limit')
const cors = require('cors')// 安全头设置
app.use(helmet())// CORS 配置
app.use(cors({origin: ['https://example.com', 'http://localhost:3000'],credentials: true
}))// 速率限制
const limiter = rateLimit({windowMs: 15 * 60 * 1000, // 15分钟max: 100 // 限制每个IP 100次请求
})
app.use('/api', limiter)// 数据清理
const mongoSanitize = require('express-mongo-sanitize')
app.use(mongoSanitize())13. 生产环境配置
环境变量管理
// .env
NODE_ENV=production
PORT=3000
DB_URL=mongodb://localhost:27017/myapp
JWT_SECRET=your-secret-key// app.js
require('dotenv').config()const PORT = process.env.PORT || 3000
const DB_URL = process.env.DB_URL进程管理
// package.json
{"scripts": {"start": "node app.js","dev": "nodemon app.js","production": "pm2 start app.js -i max"}
}14. 完整示例项目
项目结构
project/ ├── src/ │ ├── app.js │ ├── config/ │ │ └── database.js │ ├── routes/ │ │ ├── index.js │ │ ├── users.js │ │ └── auth.js │ ├── middleware/ │ │ ├── auth.js │ │ └── errorHandler.js │ ├── models/ │ │ └── User.js │ └── controllers/ │ └── userController.js ├── public/ ├── views/ ├── .env └── package.json
主应用文件
// src/app.js
const express = require('express')
const cors = require('cors')
const helmet = require('helmet')
const morgan = require('morgan')const app = express()// 中间件
app.use(helmet())
app.use(cors())
app.use(morgan('combined'))
app.use(express.json())
app.use(express.static('public'))// 路由
app.use('/', require('./routes/index'))
app.use('/api/users', require('./routes/users'))
app.use('/api/auth', require('./routes/auth'))// 错误处理
app.use(require('./middleware/errorHandler'))// 404 处理
app.use('*', (req, res) => {res.status(404).json({ error: '路由不存在' })
})const PORT = process.env.PORT || 3000
app.listen(PORT, () => {console.log(`服务器运行在端口 ${PORT}`)
})module.exports = app15. 优势总结
优点
简单易学 - API 简洁直观
灵活自由 - 无强制约束,可按需配置
生态丰富 - 海量中间件和插件
性能优秀 - 轻量级,开销小
社区活跃 - 大量教程和资源
易于扩展 - 模块化设计
注意事项
需要更多配置 - 相比全栈框架需要手动配置更多东西
架构依赖开发者 - 需要自己设计项目结构
安全性需要手动处理 - 需要安装和配置安全中间件
16. 适用场景
🚀 RESTful API 开发
🏢 微服务架构
📱 后端服务
🔧 需要高度自定义的项目
🎓 学习 Node.js Web 开发
Express.js 是 Node.js 生态中最基础、最流行的 Web 框架,几乎所有的 Node.js 开发者都应该掌握它。
