Node.js 面试题详细答案 - Q16
Q16: Express.js 是什么?它的核心特性有哪些?
Express.js 概述
Express.js 是一个基于 Node.js 平台的 Web 应用开发框架,提供了一系列强大特性来简化 Web 应用的开发。
核心特性
1. 路由系统
const express = require('express')
const app = express()
// 基本路由
app.get('/', (req, res) => {
res.send('Hello World')
})
app.post('/users', (req, res) => {
res.json({ message: '创建用户' })
})
// 路由参数
app.get('/users/:id', (req, res) => {
res.json({ userId: req.params.id })
})
// 查询参数
app.get('/search', (req, res) => {
res.json({ query: req.query.q })
})
2. 中间件支持
// 内置中间件
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(express.static('public'))
// 自定义中间件
app.use((req, res, next) => {
console.log('请求时间:', new Date())
next()
})
// 错误处理中间件
app.use((err, req, res, next) => {
console.error(err.stack)
res.status(500).send('服务器错误')
})
3. 模板引擎支持
// 设置模板引擎
app.set('view engine', 'ejs')
app.set('views', './views')
// 渲染模板
app.get('/profile', (req, res) => {
res.render('profile', {
user: { name: 'John', email: 'john@example.com' },
})
})
4. 静态文件服务
// 提供静态文件
app.use(express.static('public'))
// 多个静态目录
app.use('/css', express.static('css'))
app.use('/js', express.static('js'))
app.use('/images', express.static('images'))
实际应用示例
1. 基本 Web 服务器
const express = require('express')
const app = express()
const port = 3000
// 中间件
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
// 路由
app.get('/', (req, res) => {
res.send('欢迎使用 Express.js')
})
app.get('/api/users', (req, res) => {
const users = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
]
res.json(users)
})
app.post('/api/users', (req, res) => {
const { name, email } = req.body
res.json({ message: '用户创建成功', user: { name, email } })
})
app.listen(port, () => {
console.log(`服务器运行在 http://localhost:${port}`)
})
2. 路由模块化
// routes/users.js
const express = require('express')
const router = express.Router()
router.get('/', (req, res) => {
res.json({ message: '获取所有用户' })
})
router.get('/:id', (req, res) => {
res.json({ message: `获取用户 ${req.params.id}` })
})
router.post('/', (req, res) => {
res.json({ message: '创建用户' })
})
module.exports = router
// app.js
const userRoutes = require('./routes/users')
app.use('/api/users', userRoutes)
3. 中间件链
// 认证中间件
function authenticate(req, res, next) {
const token = req.headers.authorization
if (token === 'valid-token') {
req.user = { id: 1, name: 'John' }
next()
} else {
res.status(401).json({ error: '未授权' })
}
}
// 日志中间件
function logger(req, res, next) {
console.log(`${req.method} ${req.url} - ${new Date()}`)
next()
}
// 使用中间件
app.use(logger)
app.use('/api/protected', authenticate)
app.get('/api/protected/data', (req, res) => {
res.json({ message: '受保护的数据', user: req.user })
})
高级特性
1. 错误处理
// 同步错误处理
app.get('/error', (req, res) => {
throw new Error('同步错误')
})
// 异步错误处理
app.get('/async-error', async (req, res, next) => {
try {
await someAsyncOperation()
} catch (error) {
next(error)
}
})
// 全局错误处理
app.use((err, req, res, next) => {
console.error(err.stack)
if (err.name === 'ValidationError') {
res.status(400).json({ error: '验证错误' })
} else {
res.status(500).json({ error: '服务器错误' })
}
})
2. 请求处理
// 请求体解析
app.use(express.json({ limit: '10mb' }))
app.use(express.urlencoded({ extended: true, limit: '10mb' }))
// 文件上传
const multer = require('multer')
const upload = multer({ dest: 'uploads/' })
app.post('/upload', upload.single('file'), (req, res) => {
res.json({ message: '文件上传成功', file: req.file })
})
// 多文件上传
app.post('/upload-multiple', upload.array('files', 5), (req, res) => {
res.json({ message: '多文件上传成功', files: req.files })
})
3. 响应处理
// 不同响应类型
app.get('/response-types', (req, res) => {
const type = req.query.type
switch (type) {
case 'json':
res.json({ message: 'JSON 响应' })
break
case 'html':
res.send('<h1>HTML 响应</h1>')
break
case 'file':
res.download('path/to/file.pdf')
break
case 'redirect':
res.redirect('/')
break
default:
res.status(400).json({ error: '无效的响应类型' })
}
})
性能优化
1. 压缩响应
const compression = require('compression')
app.use(compression())
2. 缓存控制
// 设置缓存头
app.use((req, res, next) => {
if (req.url.startsWith('/static/')) {
res.set('Cache-Control', 'public, max-age=31536000')
}
next()
})
3. 请求限制
const rateLimit = require('express-rate-limit')
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分钟
max: 100, // 限制每个IP 100次请求
message: '请求过于频繁',
})
app.use('/api/', limiter)
安全特性
1. 安全头设置
const helmet = require('helmet')
app.use(helmet())
2. CORS 配置
const cors = require('cors')
app.use(
cors({
origin: ['http://localhost:3000', 'https://example.com'],
credentials: true,
})
)
3. 输入验证
const { body, validationResult } = require('express-validator')
app.post(
'/users',
[
body('name').isLength({ min: 2 }).withMessage('姓名至少2个字符'),
body('email').isEmail().withMessage('无效的邮箱格式'),
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() })
}
res.json({ message: '用户创建成功' })
}
)
部署和配置
1. 环境配置
const config = {
development: {
port: 3000,
db: 'mongodb://localhost:27017/dev',
},
production: {
port: process.env.PORT || 3000,
db: process.env.DATABASE_URL,
},
}
const env = process.env.NODE_ENV || 'development'
const appConfig = config[env]
app.listen(appConfig.port, () => {
console.log(`服务器运行在端口 ${appConfig.port}`)
})
2. 健康检查
app.get('/health', (req, res) => {
res.json({
status: 'OK',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
})
})
总结
- Express.js 作用:简化 Node.js Web 应用开发
- 核心特性:路由系统、中间件支持、模板引擎、静态文件服务
- 路由系统:支持 RESTful API 和动态路由
- 中间件:可插拔的功能模块,支持请求处理链
- 模板引擎:支持多种模板引擎渲染
- 静态文件:内置静态文件服务功能
- 错误处理:完善的错误处理机制
- 性能优化:支持压缩、缓存、请求限制
- 安全特性:支持安全头、CORS、输入验证
- 部署友好:支持环境配置和健康检查