一、Express 简介与安装
什么是 Express
Express 是一个基于 Node.js 的极简且灵活的 Web 应用程序框架,提供了一组强大的功能,适用于 Web 和移动应用程序的开发。它构建在 Node.js 的 HTTP 模块之上,简化了服务器端应用程序的开发过程。
安装 Express
在使用 Express 之前,需要先安装它。Express 通过 npm(Node Package Manager)进行安装和管理。
# 创建项目目录
mkdir my-express-app
cd my-express-app
# 初始化项目(创建 package.json)
npm init -y
# 安装 Express
npm install express
二、应用创建
最简单的 Express 应用
// 引入 Express 模块
const express = require('express');
// 创建 Express 应用实例
const app = express();
// 定义路由
app.get('/', (req, res) => {
res.send('Hello World!');
});
// 启动服务器,监听指定端口
const PORT = 3000;
app.listen(PORT, () => {
console.log(`服务器运行在 http://localhost:${PORT}`);
});
express() 函数
express() 是一个工厂函数,用于创建 Express 应用实例。这个实例包含了所有 Express 的功能,包括路由、中间件、模板引擎等。
const express = require('express');
const app = express(); // 创建应用实例
// app 对象现在包含了所有 Express 的方法和属性
console.log(typeof app); // 'function'(实际上是一个函数对象)
app.listen() 方法
app.listen() 方法用于启动服务器并开始监听指定端口的 HTTP 请求。它是 Express 应用启动的关键方法。
基本语法:
app.listen(port, callback)
参数说明:
port: 要监听的端口号(数字)- 端口号范围:有效端口号为 0-65535
- 推荐端口:开发环境常用 3000、3001、8000、8080、5000 等
- 不能使用的端口:
- 0-1023:系统保留端口(需要管理员权限),常见的有:
- 80:HTTP(通常需要 root 权限)
- 443:HTTPS(通常需要 root 权限)
- 22:SSH
- 21:FTP
- 25:SMTP
- 3306:MySQL
- 5432:PostgreSQL
- 1024-49151:注册端口(IANA 注册),应避免与已知服务冲突
- 49152-65535:动态/私有端口(相对安全,适合开发使用)
- 0-1023:系统保留端口(需要管理员权限),常见的有:
- 注意事项:如果端口已被占用,会抛出
EADDRINUSE错误
callback: 服务器启动后执行的回调函数(可选)
示例:
const express = require('express');
const app = express();
// 方式一:只指定端口
app.listen(3000);
// 方式二:指定端口和回调函数(推荐)
app.listen(3000, () => {
console.log('服务器运行在 3000 端口');
});
// 方式三:使用环境变量配置端口
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`服务器运行在 ${PORT} 端口`);
});
使用 Node.js HTTP 模块(底层方式):
Express 的 app.listen() 实际上是对 Node.js http.createServer() 的封装。你也可以直接使用 HTTP 模块:
const express = require('express');
const http = require('http');
const app = express();
const server = http.createServer(app);
server.listen(3000, () => {
console.log('服务器运行在 3000 端口');
});
基本应用结构
一个典型的 Express 应用结构如下:
const express = require('express');
const app = express();
// 1. 配置中间件
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// 2. 定义路由
app.get('/', (req, res) => {
res.send('Hello World!');
});
// 3. 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`服务器运行在 http://localhost:${PORT}`);
});
三、环境变量
process.env
process.env 是 Node.js 的全局对象,用于访问环境变量。在 Express 应用中,常用环境变量来配置端口、数据库连接等。
基本用法
// 获取环境变量
const PORT = process.env.PORT || 3000;
const NODE_ENV = process.env.NODE_ENV || 'development';
app.listen(PORT, () => {
console.log(`服务器运行在 ${PORT} 端口`);
console.log(`当前环境: ${NODE_ENV}`);
});
环境配置
使用 .env 文件
安装 dotenv 包来管理环境变量:
npm install dotenv
创建 .env 文件:
PORT=3000
NODE_ENV=development
DATABASE_URL=mongodb://localhost:27017/myapp
JWT_SECRET=your-secret-key
在应用入口文件中加载:
require('dotenv').config();
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
const NODE_ENV = process.env.NODE_ENV || 'development';
app.listen(PORT, () => {
console.log(`服务器运行在 ${PORT} 端口`);
console.log(`当前环境: ${NODE_ENV}`);
});
开发/生产环境区分
require('dotenv').config();
const express = require('express');
const app = express();
const NODE_ENV = process.env.NODE_ENV || 'development';
const PORT = process.env.PORT || 3000;
// 根据环境配置不同的行为
if (NODE_ENV === 'development') {
// 开发环境:启用详细日志
app.use((req, res, next) => {
console.log(`${req.method} ${req.path}`);
next();
});
} else if (NODE_ENV === 'production') {
// 生产环境:启用压缩、安全头等
app.use(express.static('public'));
}
app.get('/', (req, res) => {
res.json({
message: 'Hello World!',
environment: NODE_ENV
});
});
app.listen(PORT, () => {
console.log(`服务器运行在 ${PORT} 端口`);
console.log(`环境: ${NODE_ENV}`);
});
四、应用配置
app.set() - 设置应用配置
app.set() 用于设置应用级别的配置值。
const express = require('express');
const app = express();
// 设置配置项
app.set('port', 3000);
app.set('env', 'development');
app.set('view engine', 'ejs'); // 设置模板引擎
app.set('views', './views'); // 设置视图目录
app.get() - 获取应用配置
app.get() 用于获取应用级别的配置值。
const express = require('express');
const app = express();
// 设置配置
app.set('port', 3000);
app.set('env', 'development');
// 获取配置
const port = app.get('port');
const env = app.get('env');
console.log(`端口: ${port}`); // 端口: 3000
console.log(`环境: ${env}`); // 环境: development
应用级配置
Express 提供了一些内置的配置项:
const express = require('express');
const app = express();
// 常用配置项
app.set('env', process.env.NODE_ENV || 'development'); // 环境
app.set('port', process.env.PORT || 3000); // 端口
app.set('view engine', 'ejs'); // 模板引擎
app.set('views', './views'); // 视图目录
app.set('json spaces', 2); // JSON 格式化空格数
app.set('x-powered-by', false); // 禁用 X-Powered-By 头
// 获取配置
const port = app.get('port');
app.listen(port, () => {
console.log(`服务器运行在 ${port} 端口`);
});
五、核心对象
请求对象(req)
请求对象(req)代表 HTTP 请求,包含了客户端发送的所有信息,包括请求头、请求参数、请求体等。
req 的常用属性
app.get('/example', (req, res) => {
// 请求方法
console.log(req.method); // 'GET'
// 请求路径(不包含查询字符串)
console.log(req.path); // '/example'
// 完整 URL(包含查询字符串)
console.log(req.url); // '/example?name=John'
// 请求头
console.log(req.headers); // 请求头对象
// 客户端 IP 地址
console.log(req.ip); // '::ffff:127.0.0.1'
// 协议
console.log(req.protocol); // 'http'
// 主机名
console.log(req.hostname); // 'localhost'
res.send('查看控制台输出');
});
响应对象(res)
响应对象(res)代表 HTTP 响应,用于向客户端发送数据、设置响应头、设置状态码等。
res 的常用属性
app.get('/example', (req, res) => {
// 设置响应头
res.set('Content-Type', 'application/json');
// 获取响应头
const contentType = res.get('Content-Type');
// 设置状态码
res.status(200);
// 发送响应
res.json({ message: 'Hello' });
});
六、请求对象扩展
req.params - 路径参数
路径参数是 URL 路径中的动态部分,使用 : 定义,通过 req.params 对象访问。
基本用法
// 定义路径参数
app.get('/users/:id', (req, res) => {
console.log(req.params); // { id: '123' }
console.log(req.params.id); // '123'
res.json({
userId: req.params.id,
message: '获取用户信息'
});
});
// 访问 /users/123
// req.params = { id: '123' }
多个路径参数
一个路由可以定义多个路径参数:
app.get('/users/:userId/posts/:postId', (req, res) => {
console.log(req.params);
// 访问 /users/123/posts/456
// req.params = { userId: '123', postId: '456' }
res.json({
userId: req.params.userId,
postId: req.params.postId
});
});
req.query - 查询参数
查询参数是 URL 中 ? 后面的键值对,通过 req.query 对象访问。查询参数用于过滤、排序、分页等操作。
基本用法
// 访问 /search?q=express&page=1
app.get('/search', (req, res) => {
console.log(req.query); // { q: 'express', page: '1' }
console.log(req.query.q); // 'express'
console.log(req.query.page); // '1'
res.json({
query: req.query.q,
page: req.query.page
});
});
多个查询参数
// 访问 /products?category=electronics&minPrice=100&maxPrice=500&sort=price
app.get('/products', (req, res) => {
const { category, minPrice, maxPrice, sort } = req.query;
console.log('分类:', category);
console.log('最低价格:', minPrice);
console.log('最高价格:', maxPrice);
console.log('排序:', sort);
res.json({
category: category,
minPrice: minPrice,
maxPrice: maxPrice,
sort: sort
});
});
数组查询参数
查询参数可以是数组:
// 访问 /products?tags=javascript&tags=nodejs&tags=express
app.get('/products', (req, res) => {
console.log(req.query.tags); // ['javascript', 'nodejs', 'express']
res.json({
tags: req.query.tags
});
});
req.body - 请求体
请求体包含 POST、PUT 等请求中发送的数据。需要中间件来解析(如 express.json())。
JSON 数据
// 需要先配置中间件
app.use(express.json());
app.post('/users', (req, res) => {
console.log(req.body); // { name: 'John', email: 'john@example.com' }
console.log(req.body.name); // 'John'
res.json({
id: 1,
name: req.body.name,
email: req.body.email
});
});
URL 编码数据
// 配置中间件解析 URL 编码数据
app.use(express.urlencoded({ extended: true }));
app.post('/users', (req, res) => {
console.log(req.body); // { name: 'John', email: 'john@example.com' }
res.json({
id: 1,
name: req.body.name,
email: req.body.email
});
});
七、响应方法
res.send() - 通用响应方法
res.send() 是最灵活的响应方法,可以发送各种类型的数据。Express 会根据数据类型自动设置适当的 Content-Type。
app.get('/', (req, res) => {
res.send('Hello World!'); // 发送字符串,Content-Type: text/html
});
app.get('/json', (req, res) => {
res.send({ message: 'Hello' }); // 发送对象,Content-Type: application/json
});
app.get('/buffer', (req, res) => {
res.send(Buffer.from('Hello')); // 发送 Buffer,Content-Type: application/octet-stream
});
app.get('/api/users', (req, res) => {
res.send([
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' }
]); // 发送数组,Content-Type: application/json
});
res.json() - JSON 响应
res.json() 专门用于发送 JSON 响应,会自动设置 Content-Type 为 application/json,并调用 JSON.stringify()。
app.get('/api/user', (req, res) => {
res.json({
id: 1,
name: 'John Doe',
email: 'john@example.com'
});
});
app.get('/api/users', (req, res) => {
res.json([
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' }
]);
});
res.status() - 设置状态码
res.status() 用于设置 HTTP 响应状态码,通常与其他响应方法链式调用。
// 成功响应(200)
app.get('/success', (req, res) => {
res.status(200).json({ message: '成功' });
});
// 创建成功(201)
app.post('/users', (req, res) => {
res.status(201).json({ id: 1, name: 'John' });
});
// 未找到(404)
app.get('/not-found', (req, res) => {
res.status(404).json({ error: '资源未找到' });
});
// 服务器错误(500)
app.get('/error', (req, res) => {
res.status(500).json({ error: '服务器内部错误' });
});
常用 HTTP 状态码
// 2xx - 成功
res.status(200).json({ message: 'OK' }); // 成功
res.status(201).json({ message: 'Created' }); // 创建成功
res.status(204).send(); // 无内容(常用于 DELETE)
// 4xx - 客户端错误
res.status(400).json({ error: 'Bad Request' }); // 请求错误
res.status(401).json({ error: 'Unauthorized' }); // 未授权
res.status(403).json({ error: 'Forbidden' }); // 禁止访问
res.status(404).json({ error: 'Not Found' }); // 未找到
res.status(409).json({ error: 'Conflict' }); // 冲突
// 5xx - 服务器错误
res.status(500).json({ error: 'Internal Server Error' }); // 服务器错误
res.status(503).json({ error: 'Service Unavailable' }); // 服务不可用
res.redirect() - 重定向
res.redirect() 用于将客户端重定向到另一个 URL。这对于页面跳转、URL 重写等场景非常有用。
// 临时重定向(302)
app.get('/old-page', (req, res) => {
res.redirect('/new-page');
});
// 永久重定向(301)
app.get('/old-url', (req, res) => {
res.redirect(301, '/new-url');
});
// 重定向到外部 URL
app.get('/external', (req, res) => {
res.redirect('https://www.example.com');
});
// 重定向到相对路径
app.get('/login', (req, res) => {
// 登录成功后重定向到首页
res.redirect('/');
});
app.get('/users/:id/edit', (req, res) => {
// 编辑完成后重定向到用户详情页
const userId = req.params.id;
res.redirect(`/users/${userId}`);
});
八、路由定义
路由是 Express 应用的核心功能之一。它定义了应用如何响应客户端对不同 URL 路径和 HTTP 方法的请求。
什么是路由
路由是指确定应用程序如何响应客户端对特定端点的请求,该端点是 URI(或路径)和特定的 HTTP 请求方法(GET、POST、PUT、DELETE 等)的组合。
路由的基本结构
每个路由都有一个或多个处理函数,当路由匹配时执行:
app.METHOD(path, handler)
app: Express 应用实例METHOD: HTTP 请求方法(get、post、put、delete 等)path: 服务器上的路径handler: 路由匹配时执行的函数
app.get() - GET 请求
GET 请求用于获取资源,是最常用的 HTTP 方法。
// 获取所有用户
app.get('/users', (req, res) => {
res.json([
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' }
]);
});
// 获取单个用户
app.get('/users/:id', (req, res) => {
const userId = req.params.id;
res.json({ id: userId, name: 'John' });
});
app.post() - POST 请求
POST 请求用于创建新资源。
// 需要配置中间件解析请求体
app.use(express.json());
// 创建用户
app.post('/users', (req, res) => {
const { name, email } = req.body;
// 创建用户的逻辑...
res.status(201).json({
id: 1,
name: name,
email: email,
message: '用户创建成功'
});
});
app.put() - PUT 请求
PUT 请求用于更新整个资源。
app.use(express.json());
// 更新用户(完整更新)
app.put('/users/:id', (req, res) => {
const userId = req.params.id;
const { name, email } = req.body;
// 更新用户的逻辑...
res.json({
id: userId,
name: name,
email: email,
message: '用户更新成功'
});
});
app.delete() - DELETE 请求
DELETE 请求用于删除资源。
// 删除用户
app.delete('/users/:id', (req, res) => {
const userId = req.params.id;
// 删除用户的逻辑...
res.status(204).send(); // 204 No Content
});
路由路径匹配
Express 支持多种路由路径匹配方式,包括字符串匹配、正则表达式匹配和参数匹配。
字符串路径匹配
最简单的路由路径是字符串匹配:
// 精确匹配
app.get('/about', (req, res) => {
res.send('关于页面');
});
// 匹配根路径
app.get('/', (req, res) => {
res.send('首页');
});
路径参数匹配
使用 : 定义路径参数:
// 单个参数
app.get('/users/:id', (req, res) => {
res.json({ userId: req.params.id });
});
// 多个参数
app.get('/users/:userId/posts/:postId', (req, res) => {
res.json({
userId: req.params.userId,
postId: req.params.postId
});
});
可选参数
使用 ? 定义可选参数:
// /users 和 /users/:id 都可以匹配
app.get('/users/:id?', (req, res) => {
if (req.params.id) {
res.json({ userId: req.params.id });
} else {
res.json({ message: '所有用户' });
}
});
通配符匹配
使用 * 进行通配符匹配:
// 匹配 /users/ 后面的所有路径
app.get('/users/*', (req, res) => {
res.send('用户相关页面');
});
正则表达式匹配
使用正则表达式进行复杂匹配:
// 只匹配数字 ID
app.get('/users/:id(\\d+)', (req, res) => {
res.json({ userId: req.params.id });
});
// 匹配特定格式
app.get('/files/:filename(.*\\.(jpg|png|gif))', (req, res) => {
res.send(`图片文件: ${req.params.filename}`);
});
九、路由参数
路径参数和查询参数是 Express 路由中两种重要的参数类型。详细的使用方法请参考"六、请求对象扩展"章节。本节重点说明两者的区别和使用场景。
路径参数(:id、req.params)
路径参数是 URL 路径中的动态部分,使用 : 定义,通过 req.params 对象访问。详细用法请参考"六、请求对象扩展"章节中的 req.params 部分。
特点:
- 用于标识资源(如用户 ID、文章 ID)
- URL 路径的一部分,必需
- 示例:
/users/123(123 是用户 ID)
路径参数命名规则:
- 名称可以是字母、数字和下划线的组合
- 不能包含特殊字符(如连字符)
// 有效
app.get('/users/:id', handler);
app.get('/users/:userId', handler);
app.get('/users/:user_id', handler);
// 无效(不能包含特殊字符)
// app.get('/users/:user-id', handler); // 错误
查询参数(req.query)
查询参数是 URL 中 ? 后面的键值对,通过 req.query 对象访问。详细用法请参考"六、请求对象扩展"章节中的 req.query 部分。
特点:
- 用于过滤、排序、分页等操作
- URL 的可选部分
- 示例:
/users?page=1&limit=10(page 和 limit 用于分页)
路径参数 vs 查询参数
理解路径参数和查询参数的区别和使用场景很重要:
| 特性 | 路径参数(req.params) | 查询参数(req.query) |
|---|---|---|
| 用途 | 标识资源(如用户 ID、文章 ID) | 过滤、排序、分页等操作 |
| 位置 | URL 路径的一部分 | URL 中 ? 后面的键值对 |
| 是否必需 | 必需(定义在路由路径中) | 可选 |
| 示例 | /users/123(123 是用户 ID) | /users?page=1&limit=10(分页参数) |
| 组合使用 | 可以同时使用:/users/123/posts?page=1 |
最佳实践:
- 使用路径参数标识资源:
GET /users/:id、DELETE /posts/:id - 使用查询参数进行过滤和分页:
GET /users?page=1&limit=10&role=admin
十、路由模块化
express.Router()
express.Router() 用于创建模块化的路由处理器。它允许将路由组织到单独的文件中,使代码更加清晰和可维护。
基本用法
创建一个路由模块:
// routes/users.js
const express = require('express');
const router = express.Router();
// 定义路由
router.get('/', (req, res) => {
res.json([{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]);
});
router.get('/:id', (req, res) => {
res.json({ id: req.params.id, name: 'John' });
});
router.post('/', (req, res) => {
res.status(201).json({ id: 1, name: req.body.name });
});
module.exports = router;
在主应用中使用:
// app.js
const express = require('express');
const usersRouter = require('./routes/users');
const app = express();
app.use(express.json());
// 挂载路由
app.use('/users', usersRouter);
app.listen(3000, () => {
console.log('服务器运行在 3000 端口');
});
路由分离
将不同功能的路由分离到不同的文件中:
// 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}` });
});
module.exports = router;
// routes/posts.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}` });
});
module.exports = router;
// app.js
const express = require('express');
const usersRouter = require('./routes/users');
const postsRouter = require('./routes/posts');
const app = express();
app.use(express.json());
// 挂载路由
app.use('/users', usersRouter);
app.use('/posts', postsRouter);
app.listen(3000, () => {
console.log('服务器运行在 3000 端口');
});
路由模块化
在路由模块中可以定义中间件:
// routes/users.js
const express = require('express');
const router = express.Router();
// 路由级别的中间件
router.use((req, res, next) => {
console.log('用户路由请求:', req.method, req.path);
next();
});
router.get('/', (req, res) => {
res.json([{ id: 1, name: 'John' }]);
});
router.get('/:id', (req, res) => {
res.json({ id: req.params.id, name: 'John' });
});
module.exports = router;
路由组织
可以创建嵌套的路由结构:
// 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.get('/:id/posts', (req, res) => {
res.json({ message: `获取用户 ${req.params.id} 的文章` });
});
module.exports = router;
app.use() 挂载路由
使用 app.use() 将路由挂载到应用上:
const express = require('express');
const usersRouter = require('./routes/users');
const postsRouter = require('./routes/posts');
const app = express();
app.use(express.json());
// 挂载路由(无前缀)
app.use(usersRouter);
// 挂载路由(带前缀)
app.use('/api/users', usersRouter);
app.use('/api/posts', postsRouter);
app.listen(3000, () => {
console.log('服务器运行在 3000 端口');
});
路由前缀
使用路由前缀可以统一管理 API 版本或路径:
// app.js
const express = require('express');
const usersRouter = require('./routes/users');
const postsRouter = require('./routes/posts');
const app = express();
app.use(express.json());
// 使用路由前缀
app.use('/api/v1/users', usersRouter);
app.use('/api/v1/posts', postsRouter);
// 或者统一前缀
const apiRouter = express.Router();
apiRouter.use('/users', usersRouter);
apiRouter.use('/posts', postsRouter);
app.use('/api/v1', apiRouter);
app.listen(3000, () => {
console.log('服务器运行在 3000 端口');
});
十一、完整示例:RESTful API
下面是一个完整的 RESTful API 示例,展示了 Express 的各种功能的使用:
const express = require('express');
const app = express();
// 配置中间件解析 JSON 请求体
app.use(express.json());
// 模拟数据存储
let users = [
{ id: 1, name: 'John Doe', email: 'john@example.com' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }
];
// GET /users - 获取所有用户(支持分页和过滤)
app.get('/users', (req, res) => {
const page = parseInt(req.query.page) || 1;
const limit = parseInt(req.query.limit) || 10;
const role = req.query.role; // 可选的角色过滤
res.status(200).json({
success: true,
page: page,
limit: limit,
count: users.length,
data: users
});
});
// GET /users/:id - 获取单个用户
app.get('/users/:id', (req, res) => {
const userId = parseInt(req.params.id);
const user = users.find(u => u.id === userId);
if (!user) {
return res.status(404).json({
success: false,
error: '用户未找到'
});
}
res.status(200).json({
success: true,
data: user
});
});
// POST /users - 创建用户
app.post('/users', (req, res) => {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({
success: false,
error: '缺少必要字段:name 和 email'
});
}
const newUser = {
id: users.length + 1,
name: name,
email: email
};
users.push(newUser);
res.status(201).json({
success: true,
message: '用户创建成功',
data: newUser
});
});
// PUT /users/:id - 更新用户(完整更新)
app.put('/users/:id', (req, res) => {
const userId = parseInt(req.params.id);
const userIndex = users.findIndex(u => u.id === userId);
if (userIndex === -1) {
return res.status(404).json({
success: false,
error: '用户未找到'
});
}
const { name, email } = req.body;
users[userIndex] = { ...users[userIndex], name, email };
res.status(200).json({
success: true,
message: '用户更新成功',
data: users[userIndex]
});
});
// DELETE /users/:id - 删除用户
app.delete('/users/:id', (req, res) => {
const userId = parseInt(req.params.id);
const userIndex = users.findIndex(u => u.id === userId);
if (userIndex === -1) {
return res.status(404).json({
success: false,
error: '用户未找到'
});
}
users.splice(userIndex, 1);
res.status(204).send(); // 204 No Content
});
// 获取用户的文章列表(路径参数 + 查询参数)
app.get('/users/:userId/posts', (req, res) => {
const userId = req.params.userId; // 路径参数
const page = parseInt(req.query.page) || 1; // 查询参数
const limit = parseInt(req.query.limit) || 10; // 查询参数
const sort = req.query.sort || 'createdAt'; // 查询参数
res.json({
userId: userId,
page: page,
limit: limit,
sort: sort,
posts: []
});
});
// 重定向示例
app.get('/home', (req, res) => {
res.redirect('/');
});
app.get('/', (req, res) => {
res.send('欢迎访问用户管理 API');
});
// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`服务器运行在 http://localhost:${PORT}`);
});
总结
- Express 简介与安装:了解 Express 是什么以及如何安装
- 应用创建:通过
express()创建应用实例,使用app.listen()启动服务器 - 环境变量:使用
process.env管理环境配置,区分开发/生产环境 - 应用配置:使用
app.set()和app.get()进行应用级配置 - 核心对象:请求对象(req)和响应对象(res)的常用属性
- 请求对象扩展:通过
req.body、req.params、req.query获取请求数据 - 响应方法:使用
res.send()、res.json()、res.status()、res.redirect()等方法发送响应 - 路由定义:使用
app.get()、app.post()、app.put()、app.delete()等方法定义路由 - 路由参数:路径参数(
:id、req.params)和查询参数(req.query)的使用 - 路由模块化:使用
express.Router()进行路由分离和模块化组织