什么是 Node.js Express 框架?
如果你正在学习后端开发,或者想用 JavaScript 构建一个 Web 服务器,那么 Node.js Express 框架一定是你绕不开的一个工具。它就像一座城市的“交通指挥中心”——负责接收所有来自客户端的请求,判断该交给哪个“道路”(路由)处理,并把结果准确无误地送回去。
Node.js 本身是一个基于 Chrome V8 引擎的 JavaScript 运行环境,它让 JavaScript 能在服务器端运行。而 Express 框架,则是在 Node.js 基础上构建的一套轻量、灵活的 Web 开发工具集。它不强制你使用某种结构或模式,而是提供一套简洁的 API,让你可以快速搭建出一个功能完整的 Web 服务。
简单来说,Node.js 是“发动机”,而 Express 框架就是“方向盘 + 油门 + 挡位系统”,帮你把代码变成可访问的网页或接口。对于初学者而言,Express 的学习曲线相对平缓,但功能却非常强大,适合从零开始构建 RESTful API、静态网站甚至全栈应用。
安装与项目初始化
在开始之前,确保你已经安装了 Node.js(建议使用 LTS 版本,如 Node 18 或 Node 20)。你可以通过命令行输入以下命令来检查版本:
node -v
如果看到类似 v18.17.0 的输出,说明安装成功。
接下来,我们创建一个名为 my-express-app 的项目目录,并初始化一个 npm 项目:
mkdir my-express-app
cd my-express-app
npm init -y
npm init -y 会自动生成一个 package.json 文件,里面包含项目的基本信息,比如名称、版本、入口文件等。
现在,我们安装 Express 框架:
npm install express
这一步会将 Express 下载到项目的 node_modules 目录中,并更新 package.json 的依赖项。
安装完成后,创建一个主入口文件 server.js,并写入最基础的代码:
// 引入 Express 框架
const express = require('express');
// 创建一个 Express 应用实例
const app = express();
// 定义一个简单的路由:当用户访问根路径 '/' 时,返回 "Hello World"
app.get('/', (req, res) => {
res.send('Hello World');
});
// 启动服务器,监听 3000 端口
app.listen(3000, () => {
console.log('服务器运行在 http://localhost:3000');
});
这段代码中:
express()创建了一个应用实例,相当于一个空的 Web 服务容器;app.get()定义了一个 GET 请求的处理逻辑,当有人访问/路径时,就会执行回调函数;res.send()用于向客户端发送响应内容;app.listen()启动服务器,监听本地 3000 端口,等待请求。
运行这个服务只需在终端输入:
node server.js
然后打开浏览器访问 http://localhost:3000,你就能看到 “Hello World” 了。
路由设计与请求处理
在 Web 开发中,路由是核心概念之一。它决定了“用户访问某个 URL,应该由哪段代码来处理”。你可以把路由想象成快递公司的分拣中心:每个包裹(请求)都有一个目的地(URL),系统必须根据地址把它分发到正确的仓库(后端处理函数)。
Express 提供了多种方法来定义路由,最常见的有 app.get、app.post、app.put、app.delete,分别对应 HTTP 的 GET、POST、PUT、DELETE 请求。
例如,我们来实现一个用户注册功能的接口:
// 定义一个 POST 路由,用于接收用户注册数据
app.post('/register', (req, res) => {
// req.body 是请求体中的数据,需要中间件支持才能获取
const { username, email } = req.body;
// 简单验证
if (!username || !email) {
return res.status(400).json({
message: '用户名和邮箱不能为空'
});
}
// 模拟保存到数据库
console.log(`用户注册成功:${username}, ${email}`);
// 返回成功响应
res.status(201).json({
message: '注册成功',
user: { username, email }
});
});
注意:
req.body是请求体数据,但默认情况下 Express 无法解析 JSON 或表单数据;- 要使用
req.body,需要引入中间件express.json(); res.status(201)设置 HTTP 状态码为 201(创建成功);res.json()会自动将对象转换为 JSON 字符串并发送。
所以,我们需要在 server.js 中添加中间件:
// 在创建 app 之后,添加中间件
app.use(express.json()); // 解析 JSON 请求体
这样,你就可以通过 Postman 或 curl 向 /register 发送 JSON 数据了。
中间件机制详解
中间件是 Node.js Express 框架中最强大、最灵活的部分。你可以把它理解为“请求的流水线”——每一个请求都会经过一系列“处理步骤”,每个步骤就是一个中间件函数。
中间件有三种类型:
- 应用级中间件(App-level middleware)
- 路由级中间件(Router-level middleware)
- 错误处理中间件(Error-handling middleware)
我们先来看一个简单的应用级中间件:
// 定义一个日志中间件
app.use((req, res, next) => {
console.log(`${new Date().toISOString()} - ${req.method} ${req.path}`);
next(); // 必须调用 next(),否则请求会卡住
});
这个中间件会在每个请求到达时打印日志,包括请求方法(GET、POST)和路径。next() 是关键,它表示“把控制权交给下一个中间件或路由”。
再举个例子:身份验证中间件
// 模拟身份验证中间件
const authenticate = (req, res, next) => {
const token = req.headers.authorization;
if (!token || token !== 'secret123') {
return res.status(401).json({
message: '未授权,请提供有效令牌'
});
}
// 验证通过,继续执行后续逻辑
next();
};
// 使用中间件保护某个路由
app.get('/profile', authenticate, (req, res) => {
res.json({
message: '这是你的个人信息',
user: '张三'
});
});
这样,只有携带正确 Authorization: secret123 头的请求才能访问 /profile。
中间件的顺序非常重要,Express 按照注册顺序依次执行,因此你应该把通用中间件(如日志、JSON 解析)放在前面,特定业务逻辑放在后面。
静态文件服务与模板渲染
Express 不仅能处理动态接口,还能轻松提供静态资源服务,比如 HTML、CSS、JavaScript 文件。
假设你的项目结构如下:
my-express-app/
├── public/
│ ├── index.html
│ └── style.css
├── server.js
└── package.json
你可以在 server.js 中添加如下代码:
// 设置 public 目录为静态资源根目录
app.use(express.static('public'));
// 这样,访问 http://localhost:3000/index.html 就能直接加载页面
当请求路径是 /index.html 时,Express 会自动去 public/ 目录下查找该文件并返回。
如果你希望使用模板引擎(如 EJS、Pug),也可以轻松集成。以 EJS 为例:
npm install ejs
然后配置:
// 设置模板引擎为 EJS
app.set('view engine', 'ejs');
app.set('views', './views'); // 模板文件存放目录
创建 views/index.ejs 文件:
<!DOCTYPE html>
<html>
<head>
<title>欢迎页面</title>
</head>
<body>
<h1>你好,<%= username %>!</h1>
<p>今天是:<%= date %></p>
</body>
</html>
在路由中渲染模板:
app.get('/', (req, res) => {
res.render('index', {
username: '小明',
date: new Date().toLocaleDateString()
});
});
这样,用户访问根路径时,Express 会自动渲染 EJS 模板,并返回 HTML 页面。
实际案例:构建一个简单的待办事项 API
我们来做一个完整的例子:一个可以增删查改待办事项的 API。
项目结构
todo-api/
├── server.js
├── data.js # 模拟数据存储
└── package.json
data.js(模拟数据库)
// 模拟待办事项列表
const todos = [
{ id: 1, title: '学习 Node.js', completed: false },
{ id: 2, title: '写博客', completed: true }
];
// 导出数据和操作函数
module.exports = {
getTodos: () => todos,
getTodoById: (id) => todos.find(t => t.id === id),
addTodo: (title) => {
const newTodo = {
id: todos.length + 1,
title,
completed: false
};
todos.push(newTodo);
return newTodo;
},
updateTodo: (id, updates) => {
const todo = todos.find(t => t.id === id);
if (!todo) return null;
Object.assign(todo, updates);
return todo;
},
deleteTodo: (id) => {
const index = todos.findIndex(t => t.id === id);
if (index === -1) return false;
todos.splice(index, 1);
return true;
}
};
server.js(主逻辑)
const express = require('express');
const { getTodos, getTodoById, addTodo, updateTodo, deleteTodo } = require('./data');
const app = express();
app.use(express.json()); // 解析 JSON 请求体
// 获取所有待办事项
app.get('/api/todos', (req, res) => {
res.json({
success: true,
data: getTodos()
});
});
// 获取单个待办事项
app.get('/api/todos/:id', (req, res) => {
const id = parseInt(req.params.id);
const todo = getTodoById(id);
if (!todo) {
return res.status(404).json({
success: false,
message: '待办事项不存在'
});
}
res.json({
success: true,
data: todo
});
});
// 创建新待办事项
app.post('/api/todos', (req, res) => {
const { title } = req.body;
if (!title) {
return res.status(400).json({
success: false,
message: '标题不能为空'
});
}
const newTodo = addTodo(title);
res.status(201).json({
success: true,
data: newTodo
});
});
// 更新待办事项
app.put('/api/todos/:id', (req, res) => {
const id = parseInt(req.params.id);
const { title, completed } = req.body;
const todo = updateTodo(id, { title, completed });
if (!todo) {
return res.status(404).json({
success: false,
message: '待办事项不存在'
});
}
res.json({
success: true,
data: todo
});
});
// 删除待办事项
app.delete('/api/todos/:id', (req, res) => {
const id = parseInt(req.params.id);
const success = deleteTodo(id);
if (!success) {
return res.status(404).json({
success: false,
message: '待办事项不存在'
});
}
res.json({
success: true,
message: '删除成功'
});
});
// 启动服务器
app.listen(3000, () => {
console.log('Node.js Express 框架服务已启动,访问 http://localhost:3000');
});
运行 node server.js,你就可以通过 Postman 测试这些接口了。
总结与展望
Node.js Express 框架是现代 Web 开发中不可或缺的一环。它以简洁、灵活、高性能著称,特别适合构建 API 服务、单页应用后端、微服务架构等。
从一个简单的“Hello World”开始,到构建完整的 RESTful API,你会发现 Express 的能力远不止于此。配合中间件、路由、模板引擎、数据库连接等技术,你可以轻松搭建出一个生产级别的应用。
对于初学者来说,掌握 Express 的核心概念(路由、中间件、请求/响应处理)是迈向后端开发的关键一步。而对于中级开发者,深入理解中间件机制和错误处理策略,能让你写出更健壮、可维护的代码。
如果你已经对 Node.js Express 框架有了基本认知,不妨尝试结合数据库(如 MongoDB、MySQL)、身份认证(JWT)、部署工具(Docker、PM2)等技术,进一步提升实战能力。
坚持写代码,多调试,多阅读文档,你会发现自己正在一步步成为真正的全栈开发者。