目录
[一、Express.js 简介](#一、Express.js 简介)
[二、安装 Express.js](#二、安装 Express.js)
[三、Express.js 核心概念](#三、Express.js 核心概念)
[1. 路由(Routes)](#1. 路由(Routes))
[2. 中间件(Middlewares)](#2. 中间件(Middlewares))
[3. 请求体解析](#3. 请求体解析)
[4. Express Router](#4. Express Router)
[5. 身份验证](#5. 身份验证)
[6. 错误处理](#6. 错误处理)
[四、Express.js 示例](#四、Express.js 示例)
一、Express.js 简介
Express.js 是一个基于 Node.js 的 Web 应用框架,它以简洁和灵活著称。它不强制使用特定的模板引擎或数据库,而是提供了一套强大的工具来处理 HTTP 请求、定义路由、管理中间件等。
Express.js 的主要特点包括:
-
简单易用的路由系统
-
灵活的中间件支持
-
内置对 JSON、URL 编码等数据格式的支持
-
轻量级,易于扩展
二、安装 Express.js
安装 Express.js 非常简单,只需使用 npm(Node.js 包管理器)即可。
javascript
npm install express --save
在 Express 4.16.0 及更高版本中,Express 内置了 body-parser
的核心功能,因此不再需要额外安装 body-parser
包。只需使用 Express 内置的 express.json()
和 express.urlencoded()
方法即可解析请求体。
三、Express.js 核心概念
1. 路由(Routes)
路由定义了 Express 应用如何响应客户端的 HTTP 请求。每个路由由一个 HTTP 方法(如 GET、POST、PUT、DELETE 等)和一个 URL 路径组成。
javascript
// GET 请求根路径
app.get('/', (req, res) => { res.send('Home Page'); });
// GET 请求 /hello 路径
app.get('/hello', (req, res) => { res.send('Hello World'); });
2. 中间件(Middlewares)
中间件是 Express 应用的核心概念之一。它是一种可以在请求处理管道中执行的功能,可以访问请求和响应对象,并调用 next()
函数将控制权传递给下一个中间件。
javascript
// 自定义日志记录中间件
app.use((req, res, next) => {
console.log(`${new Date().toISOString()} ${req.ip} ${req.method} ${req.path}`);
next();
});
3. 请求体解析
在 Express 4.16.0 及更高版本中,Express 内置了 body-parser
的核心功能,因此可以直接使用 express.json()
和 express.urlencoded()
方法来解析请求体。
javascript
// 解析 JSON 请求体
app.use(express.json());
// 解析 URL 编码的请求体
app.use(express.urlencoded({ extended: true }));
4. Express Router
Express Router 允许你创建独立的路由模块,便于代码的组织和复用。你可以将路由逻辑拆分成不同的文件,然后通过 app.use()
将它们挂载到主应用上。
javascript
// 创建一个路由模块
const router = express.Router();
// 定义路由
router.get('/', (req, res) => {
res.send('This is a sub-router');
});
// 将路由模块挂载到主应用
app.use('/api', router);
5. 身份验证
你可以创建自定义的身份验证中间件,用于保护特定的路由。
javascript
// 基础身份验证中间件
const authenticate = (req, res, next) => {
const authHeader = req.headers['authorization'];
if (authHeader && authHeader.startsWith('Bearer ')) {
// 在实际应用中,这里应该验证令牌的有效性
req.user = { id: 1, name: 'Admin User' };
next();
} else {
res.status(401).json({ error: 'Unauthorized' });
}
};
6. 错误处理
Express 提供了专门的错误处理中间件,用于捕获和处理应用中的错误。
javascript
// 错误处理中间件
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Something went wrong!' });
});
四、Express.js 示例
- 项目结构

- app.js (主应用文件)
javascript
const express = require("express");
const path = require("path");
const app = express();
const PORT = 3000;
// 1. 中间件设置
// 解析 JSON 请求体
app.use(express.json());
// 解析 URL 编码的请求体
app.use(express.urlencoded({ extended: true }));
const logger = (req, res, next) => {
console.log(
`${new Date().toISOString()} ${req.ip} ${req.method} ${req.path}`
);
next();
};
// 应用日志中间件
app.use(logger);
// 静态文件服务
app.use(express.static(path.join(__dirname, "public")));
// 2. 路由设置
// 导入博客路由模块
const blogRoutes = require("./blogRoutes");
// 将 API 路由挂载到主应用
app.use("/api", blogRoutes);
// 3. 错误处理中间件
// 错误处理中间件
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: "Something went wrong!" });
});
// 4. 启动服务器
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
- blogRoutes.js (路由模块)
javascript
const express = require("express");
const router = express.Router();
// 文章数据存储
let posts = [
{
id: 1,
title: "Express.js 入门教程",
content: "Express.js 是一个轻量级 Node.js Web 应用框架...",
},
{
id: 2,
title: "Node.js 基础",
content: "Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境...",
},
];
// 获取所有文章
router.get("/posts", (req, res) => {
res.json(posts);
});
// 获取单篇文章
router.get("/posts/:id", (req, res) => {
const postId = parseInt(req.params.id);
const post = posts.find((post) => post.id === postId);
if (post) {
res.json(post);
} else {
res.status(404).json({ error: "Post not found" });
}
});
// 创建新文章
router.post("/posts", (req, res) => {
if (!req.body.title || !req.body.content) {
return res.status(400).json({ error: "Title and content are required" });
}
const newPost = {
id: posts.length + 1,
title: req.body.title,
content: req.body.content,
};
posts.push(newPost);
res.status(201).json(newPost);
});
// 更新文章
router.put("/posts/:id", (req, res) => {
const postId = parseInt(req.params.id);
const updatedPost = {
id: postId,
title: req.body.title,
content: req.body.content,
};
const index = posts.findIndex((post) => post.id === postId);
if (index !== -1) {
posts[index] = updatedPost;
res.json(updatedPost);
} else {
res.status(404).json({ error: "Post not found" });
}
});
// 删除文章
router.delete("/posts/:id", (req, res) => {
const postId = parseInt(req.params.id);
const initialLength = posts.length;
posts = posts.filter((post) => post.id !== postId);
if (posts.length < initialLength) {
res.status(204).send();
} else {
res.status(404).json({ error: "Post not found" });
}
});
module.exports = router;
- public/index.html (静态页面)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Express.js 应用</title>
<link rel="stylesheet" href="/styles.css" />
</head>
<body>
<div class="container">
<h1>欢迎使用 Express.js</h1>
<p>这是一个简单的 Express.js 示例应用</p>
<ul>
<li><a href="/api/posts">模拟请求文章列表</a></li>
<li><a href="/api/posts/1">模拟请求文字详情</a></li>
</ul>
</div>
</body>
</html>
- public/styles.css (样式文件)
css
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
margin: 0;
padding: 0;
}
div.container {
width: 80%;
margin: 50px auto;
padding: 20px;
background-color: white;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
h1 {
color: #333;
}
a {
color: #007bff;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
- 页面展示