Appearance
第11章:基础实战
实战1:简单日志工具(FS模块实战)
11.1 需求分析
创建一个简单的日志工具,能够:
- 记录用户操作日志
- 将日志写入本地文件
- 支持不同级别的日志(info、warn、error、debug)
- 按日期分割日志文件
11.2 核心实现
步骤1:创建 logger.js 文件
javascript
// logger.js
const fs = require('fs').promises;
const path = require('path');
class Logger {
constructor(logDir = './logs') {
this.logDir = logDir;
this.ensureLogDir();
}
async ensureLogDir() {
try {
await fs.mkdir(this.logDir, { recursive: true });
} catch (err) {
console.error('创建日志目录失败:', err);
}
}
async log(message, level = 'info') {
try {
const timestamp = new Date().toISOString();
const logMessage = `[${timestamp}] [${level.toUpperCase()}] ${message}\n`;
const logFile = path.join(this.logDir, `${new Date().toISOString().split('T')[0]}.log`);
await fs.appendFile(logFile, logMessage);
console.log(logMessage.trim());
} catch (err) {
console.error('写入日志失败:', err);
}
}
async info(message) {
await this.log(message, 'info');
}
async error(message) {
await this.log(message, 'error');
}
async warn(message) {
await this.log(message, 'warn');
}
async debug(message) {
await this.log(message, 'debug');
}
}
module.exports = Logger;步骤2:创建使用示例
javascript
// app.js
const Logger = require('./logger');
const logger = new Logger();
async function testLogger() {
await logger.info('应用启动');
await logger.warn('配置文件未找到');
await logger.error('数据库连接失败');
await logger.debug('调试信息');
await logger.info('应用关闭');
}
testLogger();11.3 实操代码讲解与优化
代码讲解:
- 使用
fs.promises进行异步文件操作 - 使用
path模块处理文件路径 - 实现了按日期分割日志文件的功能
- 支持不同级别的日志记录
优化建议:
- 添加日志轮转功能,避免单个日志文件过大
- 添加日志压缩功能,节省存储空间
- 添加日志查询功能,方便查找历史日志
- 添加配置选项,允许用户自定义日志格式和存储位置
实战2:静态网站服务器(HTTP/Express实战)
11.4 需求分析
创建一个静态网站服务器,能够:
- 托管本地 HTML/CSS/JS 文件
- 支持浏览器访问静态页面
- 处理 404 错误
- 提供基本的日志功能
11.5 核心实现
方法1:使用原生 http 模块
javascript
// server.js
const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');
const server = http.createServer((req, res) => {
const { pathname } = url.parse(req.url);
// 静态资源目录
const staticDir = path.join(__dirname, 'public');
// 构建文件路径
let filePath = path.join(staticDir, pathname);
// 如果是目录,默认返回 index.html
if (pathname.endsWith('/')) {
filePath = path.join(filePath, 'index.html');
}
// 获取文件扩展名
const extname = path.extname(filePath);
// 设置内容类型
let contentType = 'text/plain';
switch (extname) {
case '.html':
contentType = 'text/html';
break;
case '.css':
contentType = 'text/css';
break;
case '.js':
contentType = 'text/javascript';
break;
case '.json':
contentType = 'application/json';
break;
case '.png':
contentType = 'image/png';
break;
case '.jpg':
case '.jpeg':
contentType = 'image/jpeg';
break;
case '.gif':
contentType = 'image/gif';
break;
}
// 读取文件
fs.readFile(filePath, (err, data) => {
if (err) {
// 文件不存在
if (err.code === 'ENOENT') {
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('404 Not Found');
} else {
// 其他错误
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('500 Internal Server Error');
}
return;
}
// 发送文件
res.writeHead(200, { 'Content-Type': contentType });
res.end(data);
});
});
const port = 3000;
server.listen(port, () => {
console.log(`服务器运行在 http://localhost:${port}`);
});方法2:使用 Express 框架
javascript
// server.js
const express = require('express');
const app = express();
const port = 3000;
// 托管静态资源
app.use(express.static('public'));
// 404 处理
app.use((req, res) => {
res.status(404).send('404 Not Found');
});
// 启动服务器
app.listen(port, () => {
console.log(`服务器运行在 http://localhost:${port}`);
});11.6 实操:启动服务器,浏览器访问测试
步骤1:创建静态资源目录
bash
mkdir -p public步骤2:创建 index.html 文件
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>静态网站</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Hello, Node.js 静态网站!</h1>
<p>这是一个由 Node.js 服务器托管的静态网站。</p>
<script src="script.js"></script>
</body>
</html>步骤3:创建 style.css 文件
css
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #f0f0f0;
}
h1 {
color: #333;
}
p {
color: #666;
}步骤4:创建 script.js 文件
javascript
console.log('Hello, Node.js!');
document.querySelector('p').textContent = '这是由 JavaScript 动态修改的内容!';步骤5:运行服务器
bash
node server.js步骤6:访问网站
打开浏览器,访问 http://localhost:3000,你应该能看到静态网站的内容。
实战3:简单接口开发(Express实战)
11.7 需求分析
创建一个简单的用户管理 API,能够:
- 提供用户列表接口
- 提供用户详情接口
- 支持返回 JSON 数据
- 处理错误情况
11.8 核心实现
步骤1:创建项目
bash
mkdir express-api
cd express-api
npm init -y
npm install express步骤2:创建 app.js 文件
javascript
// app.js
const express = require('express');
const app = express();
const port = 3000;
// 中间件
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// 模拟用户数据
const users = [
{ id: 1, name: '张三', age: 20, email: 'zhangsan@example.com' },
{ id: 2, name: '李四', age: 25, email: 'lisi@example.com' },
{ id: 3, name: '王五', age: 30, email: 'wangwu@example.com' }
];
// GET /api/users - 获取用户列表
app.get('/api/users', (req, res) => {
res.json({
success: true,
message: '获取用户列表成功',
data: users
});
});
// GET /api/users/:id - 获取单个用户
app.get('/api/users/:id', (req, res) => {
const id = parseInt(req.params.id);
const user = users.find(u => u.id === id);
if (user) {
res.json({
success: true,
message: '获取用户成功',
data: user
});
} else {
res.status(404).json({
success: false,
message: '用户不存在'
});
}
});
// 404 处理
app.use((req, res) => {
res.status(404).json({
success: false,
message: '接口不存在'
});
});
// 启动服务器
app.listen(port, () => {
console.log(`服务器运行在 http://localhost:${port}`);
});11.9 实操:用Postman测试接口,验证功能
步骤1:运行服务器
bash
node app.js步骤2:测试接口
使用 Postman 或 curl 测试以下接口:
获取用户列表:
bashcurl http://localhost:3000/api/users获取单个用户:
bashcurl http://localhost:3000/api/users/1测试不存在的用户:
bashcurl http://localhost:3000/api/users/999测试不存在的接口:
bashcurl http://localhost:3000/api/nonexistent
小结
- 实战1:创建了一个简单的日志工具,使用 FS 模块实现日志写入和按日期分割
- 实战2:创建了一个静态网站服务器,分别使用原生 http 模块和 Express 框架实现
- 实战3:创建了一个简单的用户管理 API,使用 Express 框架实现
- 这些基础实战案例涵盖了 Node.js 的核心功能,包括文件系统操作、HTTP 服务器创建、路由处理等
- 通过这些实战案例,你可以巩固所学的 Node.js 知识,为更复杂的项目打下基础
现在,你已经完成了基础实战,接下来让我们学习进阶实战。
