Q16: Express.js 是什么?它的核心特性有哪些?

51 阅读2分钟

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、输入验证
  • 部署友好:支持环境配置和健康检查