From 0d4e184b85a2e8654e3e2896f26682116eb18558 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E4=BF=8A=E8=B1=AA?= <2578288723@qq.com> Date: Sun, 22 Mar 2026 19:17:53 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B5=B5=E4=BF=8A=E8=B1=AA17?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...72\346\234\254\346\250\241\345\235\227.md" | 28 ++ ...07\344\273\266\346\250\241\345\235\227.md" | 115 ++++++++ ...66\346\250\241\345\235\227\347\273\255.md" | 49 ++++ .../20260320-http\346\250\241\345\235\227.md" | 246 ++++++++++++++++++ 4 files changed, 438 insertions(+) create mode 100644 "\350\265\265\344\277\212\350\261\252/20260316-\345\237\272\346\234\254\346\250\241\345\235\227.md" create mode 100644 "\350\265\265\344\277\212\350\261\252/20260318-\346\226\207\344\273\266\346\250\241\345\235\227.md" create mode 100644 "\350\265\265\344\277\212\350\261\252/20260319-\346\226\207\344\273\266\346\250\241\345\235\227\347\273\255.md" create mode 100644 "\350\265\265\344\277\212\350\261\252/20260320-http\346\250\241\345\235\227.md" diff --git "a/\350\265\265\344\277\212\350\261\252/20260316-\345\237\272\346\234\254\346\250\241\345\235\227.md" "b/\350\265\265\344\277\212\350\261\252/20260316-\345\237\272\346\234\254\346\250\241\345\235\227.md" new file mode 100644 index 0000000..71a549a --- /dev/null +++ "b/\350\265\265\344\277\212\350\261\252/20260316-\345\237\272\346\234\254\346\250\241\345\235\227.md" @@ -0,0 +1,28 @@ +| 使用console模块 | 掌握日志输出、计时、表格等方法 | +| --------------- | ------------------------------ | +| 使用process模块 | 获取进程信息、处理命令行参数 | +| 使用Buffer模块 | 创建和操作二进制数据 | +| 使用path模块 | 处理文件路径 | + +``` +// 1. console模块 - 多种输出方式 +console.log('普通信息'); +console.info('提示信息'); +console.warn('警告信息'); +console.error('错误信息'); +console.table([{name: '张三', age: 20}]); + +// 2. process模块 - 获取进程信息 +console.log('Node版本:', process.version); +console.log('平台:', process.platform); +console.log('当前目录:', process.cwd()); + +// 3. Buffer模块 - 处理二进制 +const buf = Buffer.from('Hello'); +console.log(buf); // + +// 4. path模块 - 路径处理 +const path = require('path'); +console.log(__dirname); +console.log(__filename); +``` \ No newline at end of file diff --git "a/\350\265\265\344\277\212\350\261\252/20260318-\346\226\207\344\273\266\346\250\241\345\235\227.md" "b/\350\265\265\344\277\212\350\261\252/20260318-\346\226\207\344\273\266\346\250\241\345\235\227.md" new file mode 100644 index 0000000..4948c4d --- /dev/null +++ "b/\350\265\265\344\277\212\350\261\252/20260318-\346\226\207\344\273\266\346\250\241\345\235\227.md" @@ -0,0 +1,115 @@ +### fs模块的特点 + +| 特点 | 说明 | +| -------- | ------------------------------------ | +| 功能完善 | 读写、复制、删除、移动、监听... | +| 两种方式 | 同步(带Sync)和异步(回调/Promise) | +| 流式处理 | 支持大文件流式读写 | +| 权限控制 | 支持设置文件权限 | + +### 知识点1:读取文件 + +#### 同步读取 + +``` +const fs = require('fs'); + +// 读取文件(同步) +const content = fs.readFileSync('./data.txt', 'utf8'); +console.log(content); + +// 指定编码读取 +const content2 = fs.readFileSync('./data.txt', { encoding: 'utf8' }); + +// 读取图片等二进制文件 +const buffer = fs.readFileSync('./image.png'); +``` + +#### 3.1.2 异步读取(回调方式) + +``` +const fs = require('fs'); + +// 读取文件(异步回调) +fs.readFile('./data.txt', 'utf8', (err, data) => { + if (err) { + console.error('读取失败:', err); + return; + } + console.log('文件内容:', data); +}); + +// 读取二进制 +fs.readFile('./image.png', (err, buffer) => { + if (err) throw err; + console.log('文件大小:', buffer.length, '字节'); +}); +``` + +#### 3.1.3 异步读取(Promise方式) + +``` +const fs = require('fs').promises; + +// 读取文件(Promise) +async function readFile() { + try { + const content = await fs.readFile('./data.txt', 'utf8'); + console.log(content); + } catch (err) { + console.error('读取失败:', err); + } +} + +readFile(); +``` + +### 写入文件 + +#### 3.2.1 同步写入 + +``` +const fs = require('fs'); + +// 写入文件(同步) +fs.writeFileSync('./data.txt', 'Hello World'); + +// 追加写入 +fs.appendFileSync('./log.txt', '新内容\n'); + +// 写入二进制 +const buffer = Buffer.from([1, 2, 3, 4]); +fs.writeFileSync('./data.bin', buffer); +``` + +#### 3.2.2 异步写入 + +``` +const fs = require('fs'); + +// 异步写入 +fs.writeFile('./data.txt', 'Hello World', 'utf8', (err) => { + if (err) throw err; + console.log('写入成功'); +}); + +// 异步追加 +fs.appendFile('./log.txt', '新内容\n', (err) => { + if (err) throw err; + console.log('追加成功'); +}); +``` + +### 知识点3:文件操作 + +#### .1 检查文件状态 + +#### 2 删除文件 + +#### .3 复制文件 + +#### 4 重命名和移动 + +### 知识点4:目录操作 + +### 知识点5:Watch监听文件变化 \ No newline at end of file diff --git "a/\350\265\265\344\277\212\350\261\252/20260319-\346\226\207\344\273\266\346\250\241\345\235\227\347\273\255.md" "b/\350\265\265\344\277\212\350\261\252/20260319-\346\226\207\344\273\266\346\250\241\345\235\227\347\273\255.md" new file mode 100644 index 0000000..be3f008 --- /dev/null +++ "b/\350\265\265\344\277\212\350\261\252/20260319-\346\226\207\344\273\266\346\250\241\345\235\227\347\273\255.md" @@ -0,0 +1,49 @@ +### 实现简单的文件浏览器 + +1. ``` + const fs = require('fs'); + const path = require('path'); + + // 格式化文件大小 + function formatSize(bytes) { + if (bytes === 0) return '0 B'; + const k = 1024; + const sizes = ['B', 'KB', 'MB', 'GB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return (bytes / Math.pow(k, i)).toFixed(2) + ' ' + sizes[i]; + } + + // 浏览目录 + function browse(dirPath, indent = 0) { + if (!fs.existsSync(dirPath)) { + console.log('目录不存在'); + return; + } + + const items = fs.readdirSync(dirPath, { withFileTypes: true }); + const prefix = ' '.repeat(indent); + + for (const item of items) { + const fullPath = path.join(dirPath, item.name); + + if (item.isDirectory()) { + console.log(`${prefix}📁 ${item.name}/`); + browse(fullPath, indent + 1); + } else { + const stats = fs.statSync(fullPath); + console.log(`${prefix}📄 ${item.name} (${formatSize(stats.size)})`); + } + } + } + + // 获取命令行参数 + const dir = process.argv[2] || '.'; + console.log(`\n浏览目录: ${dir}\n`); + browse(dir); + ``` + +2. 测试: + + ``` + node browser.js ./src + ``` \ No newline at end of file diff --git "a/\350\265\265\344\277\212\350\261\252/20260320-http\346\250\241\345\235\227.md" "b/\350\265\265\344\277\212\350\261\252/20260320-http\346\250\241\345\235\227.md" new file mode 100644 index 0000000..f129d6f --- /dev/null +++ "b/\350\265\265\344\277\212\350\261\252/20260320-http\346\250\241\345\235\227.md" @@ -0,0 +1,246 @@ +### 1.2 HTTP模块的作用 + +| 作用 | 说明 | +| ---------- | ----------------------- | +| 创建服务器 | 使用http.createServer() | +| 发送请求 | 使用http.request() | +| 处理请求 | 获取URL、Method、参数等 | +| 返回响应 | 发送HTML、JSON、图片等 | + +## 实施步骤 + +### 步骤一:创建简单的Web服务器 + +1. 创建项目文件夹:`http-demo` + +2. 初始化项目: + + ``` + npm init -y + ``` + +3. 创建 `server.js`: + + ``` + const http = require('http'); + + // 创建服务器 + const server = http.createServer((req, res) => { + // 获取请求路径 + const url = new URL(req.url, `http://${req.headers.host}`); + const pathname = url.pathname; + + // 设置响应头 + res.writeHead(200, { + 'Content-Type': 'text/html; charset=utf-8' + }); + + // 根据路径返回不同内容 + let content = '

欢迎访问

'; + + if (pathname === '/') { + content = '

首页

欢迎来到我的网站

'; + } else if (pathname === '/about') { + content = '

关于

这是一个Node.js学习项目

'; + } else if (pathname === '/contact') { + content = '

联系

Email: test@example.com

'; + } else { + res.statusCode = 404; + content = '

404

页面不存在

'; + } + + res.end(content); + }); + + // 监听端口 + server.listen(3000, () => { + console.log('服务器运行在 http://localhost:3000'); + }); + ``` + +4. 启动服务器: + + ``` + node server.js + ``` + +5. 访问测试: + + - 打开浏览器访问 [http://localhost:3000](https://gitee.com/link?target=http%3A%2F%2Flocalhost%3A3000) + - 访问 [http://localhost:3000/about](https://gitee.com/link?target=http%3A%2F%2Flocalhost%3A3000%2Fabout) + - 访问 [http://localhost:3000/contact](https://gitee.com/link?target=http%3A%2F%2Flocalhost%3A3000%2Fcontact) + - 访问 [http://localhost:3000/xxx(测试404)](https://gitee.com/link?target=http%3A%2F%2Flocalhost%3A3000%2Fxxx%EF%BC%88%E6%B5%8B%E8%AF%95404%EF%BC%89) + +### 步骤二:创建RESTful API + +1. 创建 `api-server.js`: + + ``` + const http = require('http'); + + // 模拟数据 + const users = [ + { id: 1, name: '张三', email: 'zhangsan@example.com' }, + { id: 2, name: '李四', email: 'lisi@example.com' } + ]; + + const server = http.createServer((req, res) => { + // 设置CORS头 + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Content-Type', 'application/json; charset=utf-8'); + + const url = new URL(req.url, `http://${req.headers.host}`); + const pathname = url.pathname; + + // GET /api/users - 获取所有用户 + if (req.method === 'GET' && pathname === '/api/users') { + res.end(JSON.stringify(users)); + } + // GET /api/users/:id - 获取单个用户 + else if (req.method === 'GET' && pathname.startsWith('/api/users/')) { + const id = parseInt(pathname.split('/').pop()); + const user = users.find(u => u.id === id); + if (user) { + res.end(JSON.stringify(user)); + } else { + res.statusCode = 404; + res.end(JSON.stringify({ error: '用户不存在' })); + } + } + // POST /api/users - 创建用户 + else if (req.method === 'POST' && pathname === '/api/users') { + let body = ''; + req.on('data', chunk => body += chunk); + req.on('end', () => { + const newUser = JSON.parse(body); + newUser.id = users.length + 1; + users.push(newUser); + res.end(JSON.stringify({ success: true, user: newUser })); + }); + } + // DELETE /api/users/:id - 删除用户 + else if (req.method === 'DELETE' && pathname.startsWith('/api/users/')) { + const id = parseInt(pathname.split('/').pop()); + const index = users.findIndex(u => u.id === id); + if (index !== -1) { + users.splice(index, 1); + res.end(JSON.stringify({ success: true })); + } else { + res.statusCode = 404; + res.end(JSON.stringify({ error: '用户不存在' })); + } + } + else { + res.statusCode = 404; + res.end(JSON.stringify({ error: 'API不存在' })); + } + }); + + server.listen(3001, () => { + console.log('API服务器运行在 http://localhost:3001'); + }); + ``` + +2. 启动并测试: + + ``` + node api-server.js + ``` + +3. 使用curl测试: + + ``` + # 获取所有用户 + curl http://localhost:3001/api/users + + # 获取单个用户 + curl http://localhost:3001/api/users/1 + + # 创建用户 + curl -X POST http://localhost:3001/api/users -H "Content-Type: application/json" -d "{\"name\":\"王五\",\"email\":\"wang@example.com\"}" + + # 删除用户 + curl -X DELETE http://localhost:3001/api/users/2 + ``` + +### 步骤三:创建HTTP客户端 + +1. 创建 `client.js`: + + ``` + const http = require('http'); + + // 发送GET请求 + function httpGet(url) { + return new Promise((resolve, reject) => { + http.get(url, (res) => { + let data = ''; + res.on('data', chunk => data += chunk); + res.on('end', () => resolve(data)); + }).on('error', reject); + }); + } + + // 发送POST请求 + function httpPost(url, data) { + return new Promise((resolve, reject) => { + const postData = JSON.stringify(data); + const urlObj = new URL(url); + + const options = { + hostname: urlObj.hostname, + port: urlObj.port || 80, + path: urlObj.pathname, + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Content-Length': Buffer.byteLength(postData) + } + }; + + const req = http.request(options, (res) => { + let data = ''; + res.on('data', chunk => data += chunk); + res.on('end', () => resolve(data)); + }); + + req.on('error', reject); + req.write(postData); + req.end(); + }); + } + + // 测试 + async function test() { + console.log('=== GET 请求 ==='); + const users = await httpGet('http://localhost:3001/api/users'); + console.log(users); + + console.log('\n=== POST 请求 ==='); + const result = await httpPost('http://localhost:3001/api/users', { + name: '测试用户', + email: 'test@example.com' + }); + console.log(result); + } + + test(); + ``` + +2. 确保API服务器运行,然后测试: + + ``` + node client.js + ``` + +## 5 小结 + +### 5.1 核心知识点 + +| 知识点 | 关键内容 | +| -------------- | --------------------------------------- | +| **创建服务器** | http.createServer() | +| **请求对象** | req.method / req.url / req.headers | +| **响应对象** | res.writeHead / res.end / res.setHeader | +| **URL解析** | new URL() / searchParams | +| **客户端** | http.get() / http.request() | \ No newline at end of file -- Gitee