NodeJs全汇总
发表于更新于
NodenodeNodeJs全汇总
OHNIINode.js基本概念
Node.js是一个基于Chrome V8 JavaScript引擎的JavaScript运行时环境,让JavaScript可以在服务器端运行。
为什么要使用Node.js
• 单线程事件循环:Node.js采用单线程事件循环模型,避免了多线程的复杂性
• 非阻塞I/O:异步I/O操作不会阻塞主线程,提高并发性能
• 跨平台:可以在Windows、macOS、Linux等操作系统上运行
• 丰富的生态系统:npm包管理器提供了大量的第三方模块
• 前后端统一:使用相同的JavaScript语言开发前后端
• 高性能:基于V8引擎,执行速度快
• 实时应用:适合构建实时应用,如聊天室、游戏服务器
• 微服务架构:轻量级,适合构建微服务
Node.js基础
1. 模块系统
概念:Node.js使用CommonJS模块系统,每个文件都是一个模块,可以通过require()导入和module.exports导出。
语法规则:
- 导入模块:
const 模块名 = require('模块路径')
- 导出模块:
module.exports = 值 或 exports.属性名 = 值
- 内置模块:直接使用模块名,如
require('fs')
- 第三方模块:使用包名,如
require('express')
作用:
- 代码组织和模块化
- 避免全局变量污染
- 提高代码复用性
- 依赖管理
基本模块使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function add(a, b) { return a + b }
function subtract(a, b) { return a - b }
module.exports = { add, subtract }
exports.multiply = (a, b) => a * b exports.divide = (a, b) => a / b
|
1 2 3 4 5 6 7 8 9 10 11
| const math = require('./math') const fs = require('fs') const express = require('express')
console.log(math.add(5, 3)) console.log(math.multiply(4, 2))
const { add, subtract } = require('./math') console.log(add(10, 5))
|
ES6模块语法(Node.js 12+)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| export function add(a, b) { return a + b }
export default function multiply(a, b) { return a * b }
import { add } from './math.mjs' import multiply from './math.mjs'
console.log(add(5, 3)) console.log(multiply(4, 2))
|
2. 文件系统操作
概念:Node.js提供了fs模块来处理文件系统操作,包括文件的读取、写入、删除等。
语法规则:
- 同步操作:
fs.readFileSync(), fs.writeFileSync()
- 异步操作:
fs.readFile(), fs.writeFile()
- Promise版本:
fs.promises.readFile(), fs.promises.writeFile()
使用场景:
- 配置文件读取
- 日志文件写入
- 静态文件服务
- 数据持久化
基本文件操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| const fs = require('fs') const path = require('path')
try { const data = fs.readFileSync('config.json', 'utf8') console.log('配置文件内容:', data) } catch (error) { console.error('读取文件失败:', error.message) }
fs.readFile('data.txt', 'utf8', (err, data) => { if (err) { console.error('读取失败:', err.message) return } console.log('文件内容:', data) })
async function readFileAsync(filename) { try { const data = await fs.promises.readFile(filename, 'utf8') return data } catch (error) { console.error('读取失败:', error.message) throw error } }
const content = 'Hello, Node.js!' fs.writeFile('output.txt', content, (err) => { if (err) { console.error('写入失败:', err.message) return } console.log('文件写入成功') })
fs.access('config.json', fs.constants.F_OK, (err) => { if (err) { console.log('文件不存在') } else { console.log('文件存在') } })
|
目录操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| fs.mkdir('new-folder', (err) => { if (err) { console.error('创建目录失败:', err.message) return } console.log('目录创建成功') })
fs.readdir('./', (err, files) => { if (err) { console.error('读取目录失败:', err.message) return } console.log('目录内容:', files) })
fs.stat('package.json', (err, stats) => { if (err) { console.error('获取文件信息失败:', err.message) return } console.log('文件大小:', stats.size) console.log('创建时间:', stats.birthtime) console.log('是否文件:', stats.isFile()) console.log('是否目录:', stats.isDirectory()) })
|
3. 路径处理
概念:Node.js提供了path模块来处理文件和目录路径,确保跨平台兼容性。
语法规则:
path.join() - 连接路径
path.resolve() - 解析绝对路径
path.dirname() - 获取目录名
path.basename() - 获取文件名
path.extname() - 获取文件扩展名
使用场景:
- 构建跨平台路径
- 文件路径解析
- 相对路径转绝对路径
- 路径拼接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| const path = require('path')
const filePath = path.join('src', 'components', 'Button.js') console.log(filePath)
const absolutePath = path.resolve('src', 'index.js') console.log(absolutePath)
const filePath2 = '/home/user/project/src/index.js' console.log(path.dirname(filePath2)) console.log(path.basename(filePath2)) console.log(path.extname(filePath2))
const messyPath = '/home/user/../user/./project//src/index.js' console.log(path.normalize(messyPath))
const from = '/home/user/project/src' const to = '/home/user/project/dist' console.log(path.relative(from, to))
|
4. 环境变量
概念:Node.js通过process.env对象访问环境变量,用于配置应用程序。
语法规则:
- 读取环境变量:
process.env.变量名
- 设置环境变量:
process.env.变量名 = 值
- 使用dotenv包:
require('dotenv').config()
使用场景:
- 数据库连接配置
- API密钥管理
- 环境特定配置
- 敏感信息存储
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| const port = process.env.PORT || 3000 const dbUrl = process.env.DATABASE_URL const apiKey = process.env.API_KEY
console.log('服务器端口:', port) console.log('数据库URL:', dbUrl)
process.env.NODE_ENV = 'production' process.env.DEBUG = 'true'
require('dotenv').config()
console.log('配置的端口:', process.env.PORT) console.log('数据库连接:', process.env.DATABASE_URL)
|
5. 命令行参数
概念:Node.js可以通过process.argv获取命令行参数,用于创建命令行工具。
语法规则:
process.argv[0] - Node.js可执行文件路径
process.argv[1] - 当前脚本文件路径
process.argv[2+] - 用户传入的参数
使用场景:
- 命令行工具开发
- 脚本参数传递
- 配置选项设置
- 批处理操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| console.log('Node.js路径:', process.argv[0]) console.log('脚本路径:', process.argv[1]) console.log('用户参数:', process.argv.slice(2))
const args = process.argv.slice(2) const options = {}
for (let i = 0; i < args.length; i++) { if (args[i].startsWith('--')) { const key = args[i].substring(2) const value = args[i + 1] options[key] = value i++ } }
console.log('解析的选项:', options)
|
6. 全局对象
概念:Node.js提供了一些全局对象,可以直接使用,无需require导入。
主要全局对象:
global - 全局命名空间
process - 进程对象
console - 控制台对象
Buffer - 缓冲区对象
__dirname - 当前文件所在目录
__filename - 当前文件完整路径
使用场景:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| console.log('当前目录:', __dirname) console.log('当前文件:', __filename)
console.log('Node.js版本:', process.version) console.log('平台:', process.platform) console.log('架构:', process.arch) console.log('内存使用:', process.memoryUsage())
const buf = Buffer.from('Hello, Node.js!', 'utf8') console.log('Buffer内容:', buf.toString()) console.log('Buffer长度:', buf.length)
global.myGlobalVar = '这是一个全局变量' console.log('全局变量:', myGlobalVar)
setTimeout(() => { console.log('3秒后执行') }, 3000)
setInterval(() => { console.log('每秒执行一次') }, 1000)
|
Node.js高级特性
1. 异步编程
概念:Node.js的核心特性是异步非阻塞I/O,通过回调函数、Promise和async/await来处理异步操作。
语法规则:
- 回调函数:
function(callback) { callback(err, data) }
- Promise:
new Promise((resolve, reject) => { })
- async/await:
async function() { await 异步操作 }
使用场景:
回调函数模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| const fs = require('fs')
fs.readFile('file1.txt', 'utf8', (err, data1) => { if (err) { console.error('读取file1失败:', err) return } fs.readFile('file2.txt', 'utf8', (err, data2) => { if (err) { console.error('读取file2失败:', err) return } fs.writeFile('output.txt', data1 + data2, (err) => { if (err) { console.error('写入失败:', err) return } console.log('文件合并完成') }) }) })
function readFileCallback(filename, callback) { fs.readFile(filename, 'utf8', (err, data) => { if (err) { callback(err, null) return } callback(null, data) }) }
readFileCallback('config.json', (err, data) => { if (err) { console.error('读取失败:', err) return } console.log('配置内容:', data) })
|
Promise模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| const fs = require('fs').promises
function readFilePromise(filename) { return new Promise((resolve, reject) => { fs.readFile(filename, 'utf8') .then(data => resolve(data)) .catch(err => reject(err)) }) }
readFilePromise('file1.txt') .then(data1 => { console.log('file1内容:', data1) return readFilePromise('file2.txt') }) .then(data2 => { console.log('file2内容:', data2) return fs.writeFile('output.txt', data1 + data2) }) .then(() => { console.log('文件合并完成') }) .catch(err => { console.error('操作失败:', err) })
Promise.all([ fs.readFile('file1.txt', 'utf8'), fs.readFile('file2.txt', 'utf8'), fs.readFile('file3.txt', 'utf8') ]) .then(results => { console.log('所有文件读取完成:', results) const combined = results.join('\n') return fs.writeFile('combined.txt', combined) }) .then(() => { console.log('文件合并完成') }) .catch(err => { console.error('并行处理失败:', err) })
|
async/await模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| async function readFilesAsync() { try { const data1 = await fs.readFile('file1.txt', 'utf8') const data2 = await fs.readFile('file2.txt', 'utf8') const combined = data1 + data2 await fs.writeFile('output.txt', combined) console.log('文件合并完成') } catch (error) { console.error('操作失败:', error) } }
async function readFilesParallel() { try { const [data1, data2, data3] = await Promise.all([ fs.readFile('file1.txt', 'utf8'), fs.readFile('file2.txt', 'utf8'), fs.readFile('file3.txt', 'utf8') ]) console.log('所有文件读取完成') const combined = [data1, data2, data3].join('\n') await fs.writeFile('combined.txt', combined) console.log('文件合并完成') } catch (error) { console.error('并行处理失败:', error) } }
async function handleErrors() { try { const data = await fs.readFile('nonexistent.txt', 'utf8') console.log(data) } catch (error) { if (error.code === 'ENOENT') { console.log('文件不存在') } else { console.error('其他错误:', error.message) } } }
|
2. 事件系统
概念:Node.js基于事件驱动架构,使用EventEmitter类来处理事件。
语法规则:
- 创建事件发射器:
new EventEmitter()
- 监听事件:
emitter.on('事件名', 回调函数)
- 发射事件:
emitter.emit('事件名', 数据)
- 移除监听器:
emitter.removeListener('事件名', 回调函数)
使用场景:
- 自定义事件处理
- 模块间通信
- 异步操作完成通知
- 状态变化通知
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| const EventEmitter = require('events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
myEmitter.on('event', (data) => { console.log('收到事件:', data) })
myEmitter.emit('event', 'Hello, Event!')
myEmitter.once('once-event', (data) => { console.log('只执行一次:', data) })
myEmitter.emit('once-event', 'First') myEmitter.emit('once-event', 'Second')
myEmitter.on('error', (err) => { console.error('发生错误:', err.message) })
myEmitter.emit('error', new Error('Something went wrong!'))
class FileWatcher extends EventEmitter { constructor(filename) { super() this.filename = filename this.watchFile() } watchFile() { const fs = require('fs') fs.watchFile(this.filename, (curr, prev) => { this.emit('change', { filename: this.filename, current: curr, previous: prev }) }) } }
const watcher = new FileWatcher('config.json') watcher.on('change', (data) => { console.log('文件发生变化:', data.filename) })
|
3. 流(Stream)
概念:流是Node.js中处理数据的抽象接口,可以高效地处理大量数据。
语法规则:
- 可读流:
fs.createReadStream()
- 可写流:
fs.createWriteStream()
- 双工流:
new Duplex()
- 转换流:
new Transform()
使用场景:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| const fs = require('fs') const { Transform } = require('stream')
const readStream = fs.createReadStream('input.txt') const writeStream = fs.createWriteStream('output.txt')
readStream.pipe(writeStream)
readStream.on('data', (chunk) => { console.log('读取数据块:', chunk.length, 'bytes') })
readStream.on('end', () => { console.log('文件读取完成') })
writeStream.on('finish', () => { console.log('文件写入完成') })
class UpperCaseTransform extends Transform { constructor() { super() } _transform(chunk, encoding, callback) { const upperChunk = chunk.toString().toUpperCase() this.push(upperChunk) callback() } }
const upperCaseTransform = new UpperCaseTransform() const readStream2 = fs.createReadStream('input.txt') const writeStream2 = fs.createWriteStream('output-upper.txt')
readStream2 .pipe(upperCaseTransform) .pipe(writeStream2)
readStream.on('error', (err) => { console.error('读取流错误:', err) })
writeStream.on('error', (err) => { console.error('写入流错误:', err) })
|
4. 子进程
概念:Node.js可以创建子进程来执行系统命令或其他程序。
语法规则:
child_process.exec() - 执行shell命令
child_process.spawn() - 启动子进程
child_process.fork() - 创建新的Node.js进程
child_process.execFile() - 执行可执行文件
使用场景:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| const { exec, spawn, fork } = require('child_process')
exec('ls -la', (error, stdout, stderr) => { if (error) { console.error('执行错误:', error) return } console.log('命令输出:', stdout) })
const ls = spawn('ls', ['-la'])
ls.stdout.on('data', (data) => { console.log('输出:', data.toString()) })
ls.stderr.on('data', (data) => { console.error('错误:', data.toString()) })
ls.on('close', (code) => { console.log('进程退出,代码:', code) })
const child = fork('./child-process.js')
child.on('message', (msg) => { console.log('收到子进程消息:', msg) })
child.send({ hello: 'world' })
process.on('message', (msg) => { console.log('子进程收到消息:', msg) process.send({ response: 'Hello from child!' }) })
|
5. 网络编程
概念:Node.js提供了http、https、net等模块来创建网络应用。
语法规则:
- HTTP服务器:
http.createServer()
- HTTP客户端:
http.request()
- TCP服务器:
net.createServer()
- UDP:
dgram.createSocket()
使用场景:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| const http = require('http') const https = require('https') const net = require('net')
const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }) res.end('<h1>Hello, Node.js!</h1>') })
server.listen(3000, () => { console.log('HTTP服务器运行在 http://localhost:3000') })
const options = { hostname: 'api.github.com', port: 443, path: '/users/octocat', method: 'GET', headers: { 'User-Agent': 'Node.js HTTP Client' } }
const req = https.request(options, (res) => { let data = '' res.on('data', (chunk) => { data += chunk }) res.on('end', () => { console.log('API响应:', JSON.parse(data)) }) })
req.on('error', (err) => { console.error('请求错误:', err) })
req.end()
const tcpServer = net.createServer((socket) => { console.log('客户端连接') socket.on('data', (data) => { console.log('收到数据:', data.toString()) socket.write('服务器收到: ' + data) }) socket.on('close', () => { console.log('客户端断开连接') }) })
tcpServer.listen(8080, () => { console.log('TCP服务器运行在端口 8080') })
|
6. 错误处理
概念:Node.js提供了多种错误处理机制,包括try-catch、错误事件、回调错误等。
语法规则:
- try-catch:
try { } catch (error) { }
- 错误事件:
process.on('uncaughtException', handler)
- 回调错误:
callback(err, data)
- Promise错误:
.catch(error => { })
使用场景:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| async function riskyOperation() { try { const data = await fs.readFile('nonexistent.txt', 'utf8') return data } catch (error) { if (error.code === 'ENOENT') { console.log('文件不存在,使用默认值') return 'default content' } else { throw error } } }
process.on('uncaughtException', (error) => { console.error('未捕获的异常:', error) process.exit(1) })
process.on('unhandledRejection', (reason, promise) => { console.error('未处理的Promise拒绝:', reason) })
class CustomError extends Error { constructor(message, code) { super(message) this.name = 'CustomError' this.code = code } }
function errorHandler(err, req, res, next) { console.error('错误:', err) if (err instanceof CustomError) { res.status(400).json({ error: err.message, code: err.code }) } else { res.status(500).json({ error: '服务器内部错误' }) } }
function validateInput(input) { if (!input) { throw new CustomError('输入不能为空', 'VALIDATION_ERROR') } if (typeof input !== 'string') { throw new CustomError('输入必须是字符串', 'TYPE_ERROR') } return input }
try { const result = validateInput('') } catch (error) { if (error instanceof CustomError) { console.log('验证错误:', error.message, error.code) } }
|
Node.js核心模块详解
1. HTTP模块
概念:Node.js内置的HTTP模块用于创建HTTP服务器和客户端。
语法规则:
- 创建服务器:
http.createServer()
- 监听端口:
server.listen(port)
- 发送请求:
http.request()
- 获取请求:
http.get()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| const http = require('http') const url = require('url')
const server = http.createServer((req, res) => { const parsedUrl = url.parse(req.url, true) const path = parsedUrl.pathname const method = req.method res.setHeader('Content-Type', 'application/json') res.setHeader('Access-Control-Allow-Origin', '*') if (path === '/api/users' && method === 'GET') { res.statusCode = 200 res.end(JSON.stringify({ users: ['张三', '李四'] })) } else if (path === '/api/users' && method === 'POST') { let body = '' req.on('data', chunk => { body += chunk.toString() }) req.on('end', () => { res.statusCode = 201 res.end(JSON.stringify({ message: '用户创建成功', data: JSON.parse(body) })) }) } else { res.statusCode = 404 res.end(JSON.stringify({ error: '接口不存在' })) } })
server.listen(3000, () => { console.log('HTTP服务器运行在端口 3000') })
const options = { hostname: 'localhost', port: 3000, path: '/api/users', method: 'GET', headers: { 'Content-Type': 'application/json' } }
const req = http.request(options, (res) => { let data = '' res.on('data', (chunk) => { data += chunk }) res.on('end', () => { console.log('响应数据:', JSON.parse(data)) }) })
req.on('error', (err) => { console.error('请求错误:', err) })
req.end()
|
2. URL模块
概念:URL模块用于解析和构造URL。
语法规则:
- 解析URL:
url.parse(urlString)
- 构造URL:
url.format(urlObject)
- 解析查询字符串:
querystring.parse()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| const url = require('url') const querystring = require('querystring')
const urlString = 'https://example.com:8080/path?name=张三&age=25#section' const parsedUrl = url.parse(urlString, true)
console.log('协议:', parsedUrl.protocol) console.log('主机:', parsedUrl.host) console.log('路径:', parsedUrl.pathname) console.log('查询参数:', parsedUrl.query) console.log('锚点:', parsedUrl.hash)
const urlObject = { protocol: 'https:', host: 'example.com:8080', pathname: '/api/users', query: { page: 1, limit: 10 } }
const constructedUrl = url.format(urlObject) console.log('构造的URL:', constructedUrl)
const queryString = 'name=张三&age=25&city=北京' const parsedQuery = querystring.parse(queryString) console.log('解析的查询参数:', parsedQuery)
const queryObject = { name: '张三', age: 25, city: '北京' } const constructedQuery = querystring.stringify(queryObject) console.log('构造的查询字符串:', constructedQuery)
|
3. Crypto模块
概念:Crypto模块提供加密功能,包括哈希、加密、解密等。
语法规则:
- 创建哈希:
crypto.createHash(algorithm)
- 加密:
crypto.createCipher()
- 解密:
crypto.createDecipher()
- 生成随机数:
crypto.randomBytes()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| const crypto = require('crypto')
function createHash(data, algorithm = 'sha256') { const hash = crypto.createHash(algorithm) hash.update(data) return hash.digest('hex') }
console.log('MD5:', createHash('Hello World', 'md5')) console.log('SHA256:', createHash('Hello World', 'sha256'))
function encrypt(text, secretKey) { const algorithm = 'aes-256-cbc' const key = crypto.scryptSync(secretKey, 'salt', 32) const iv = crypto.randomBytes(16) const cipher = crypto.createCipher(algorithm, key) let encrypted = cipher.update(text, 'utf8', 'hex') encrypted += cipher.final('hex') return iv.toString('hex') + ':' + encrypted }
function decrypt(encryptedText, secretKey) { const algorithm = 'aes-256-cbc' const key = crypto.scryptSync(secretKey, 'salt', 32) const textParts = encryptedText.split(':') const iv = Buffer.from(textParts.shift(), 'hex') const encrypted = textParts.join(':') const decipher = crypto.createDecipher(algorithm, key) let decrypted = decipher.update(encrypted, 'hex', 'utf8') decrypted += decipher.final('utf8') return decrypted }
const secretKey = 'my-secret-key' const plainText = 'Hello, World!'
const encrypted = encrypt(plainText, secretKey) console.log('加密后:', encrypted)
const decrypted = decrypt(encrypted, secretKey) console.log('解密后:', decrypted)
const randomBytes = crypto.randomBytes(16) console.log('随机字节:', randomBytes.toString('hex'))
function generateUUID() { return crypto.randomUUID() }
console.log('UUID:', generateUUID())
|
4. Buffer模块
概念:Buffer是Node.js中用于处理二进制数据的全局对象。
语法规则:
- 创建Buffer:
Buffer.from(), Buffer.alloc()
- 转换:
buffer.toString()
- 操作:
buffer.slice(), buffer.copy()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| const crypto = require('crypto')
const buf1 = Buffer.from('Hello World', 'utf8') const buf2 = Buffer.alloc(10) const buf3 = Buffer.from([1, 2, 3, 4, 5])
console.log('Buffer 1:', buf1) console.log('Buffer 2:', buf2) console.log('Buffer 3:', buf3)
console.log('长度:', buf1.length) console.log('转换为字符串:', buf1.toString('utf8')) console.log('转换为JSON:', buf1.toJSON())
const buf4 = Buffer.from('Hello ') const buf5 = Buffer.from('World') const combined = Buffer.concat([buf4, buf5]) console.log('拼接结果:', combined.toString())
const buf6 = Buffer.from('Hello') const buf7 = Buffer.from('Hello') const buf8 = Buffer.from('World')
console.log('相等比较:', buf6.equals(buf7)) console.log('不相等比较:', buf6.equals(buf8))
const sliced = buf1.slice(0, 5) console.log('切片结果:', sliced.toString())
const source = Buffer.from('Hello World') const target = Buffer.alloc(5) source.copy(target, 0, 0, 5) console.log('复制结果:', target.toString())
|
5. Cluster模块
概念:Cluster模块允许创建共享服务器端口的子进程,充分利用多核CPU。
语法规则:
- 创建集群:
cluster.fork()
- 监听事件:
cluster.on('fork', callback)
- 检查进程:
cluster.isMaster
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| const cluster = require('cluster') const numCPUs = require('os').cpus().length
if (cluster.isMaster) { console.log(`主进程 ${process.pid} 正在运行`) for (let i = 0; i < numCPUs; i++) { cluster.fork() } cluster.on('exit', (worker, code, signal) => { console.log(`工作进程 ${worker.process.pid} 已退出`) cluster.fork() }) cluster.on('online', (worker) => { console.log(`工作进程 ${worker.process.pid} 已上线`) }) } else { const express = require('express') const app = express() app.get('/', (req, res) => { res.json({ message: 'Hello from worker', pid: process.pid, timestamp: new Date().toISOString() }) }) app.listen(3000, () => { console.log(`工作进程 ${process.pid} 监听端口 3000`) }) }
|
6. OS模块
概念:OS模块提供操作系统相关的实用方法。
语法规则:
- 获取系统信息:
os.platform(), os.arch()
- 获取内存信息:
os.totalmem(), os.freemem()
- 获取CPU信息:
os.cpus()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| const os = require('os')
console.log('操作系统:', os.platform()) console.log('架构:', os.arch()) console.log('主机名:', os.hostname()) console.log('系统类型:', os.type()) console.log('系统版本:', os.release())
console.log('总内存:', Math.round(os.totalmem() / 1024 / 1024 / 1024), 'GB') console.log('空闲内存:', Math.round(os.freemem() / 1024 / 1024 / 1024), 'GB') console.log('内存使用率:', Math.round((1 - os.freemem() / os.totalmem()) * 100), '%')
const cpus = os.cpus() console.log('CPU核心数:', cpus.length) console.log('CPU型号:', cpus[0].model) console.log('CPU速度:', cpus[0].speed, 'MHz')
const networkInterfaces = os.networkInterfaces() console.log('网络接口:', Object.keys(networkInterfaces))
console.log('用户信息:', os.userInfo()) console.log('临时目录:', os.tmpdir()) console.log('主目录:', os.homedir())
console.log('系统运行时间:', Math.round(os.uptime() / 3600), '小时')
|
7. Util模块
概念:Util模块提供实用工具函数。
语法规则:
- 回调转Promise:
util.promisify()
- 继承:
util.inherits()
- 调试:
util.inspect()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| const util = require('util') const fs = require('fs')
const readFile = util.promisify(fs.readFile) const writeFile = util.promisify(fs.writeFile)
async function fileOperations() { try { const data = await readFile('package.json', 'utf8') console.log('文件内容:', data) await writeFile('output.txt', 'Hello, World!') console.log('文件写入成功') } catch (error) { console.error('文件操作错误:', error) } }
fileOperations()
function BaseClass() { this.name = 'Base' }
BaseClass.prototype.sayHello = function() { console.log(`Hello from ${this.name}`) }
function DerivedClass() { BaseClass.call(this) this.name = 'Derived' }
util.inherits(DerivedClass, BaseClass)
const instance = new DerivedClass() instance.sayHello()
const obj = { name: '张三', age: 25, hobbies: ['读书', '游泳', '编程'], address: { city: '北京', district: '朝阳区' } }
console.log('调试输出:', util.inspect(obj, { colors: true, depth: 2, showHidden: false }))
const formatted = util.format('用户 %s 今年 %d 岁', '张三', 25) console.log('格式化字符串:', formatted)
console.log('是否为数组:', util.isArray([1, 2, 3])) console.log('是否为日期:', util.isDate(new Date())) console.log('是否为错误:', util.isError(new Error('测试错误')))
|
8. Events模块
概念:Events模块是Node.js事件驱动架构的核心。
语法规则:
- 创建事件发射器:
new EventEmitter()
- 监听事件:
emitter.on(), emitter.once()
- 发射事件:
emitter.emit()
- 移除监听器:
emitter.removeListener()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| const EventEmitter = require('events')
class MyEmitter extends EventEmitter { constructor() { super() this.maxListeners = 10 } start() { this.emit('start', { timestamp: new Date() }) } stop() { this.emit('stop', { timestamp: new Date() }) } }
const myEmitter = new MyEmitter()
myEmitter.on('start', (data) => { console.log('开始事件:', data) })
myEmitter.once('stop', (data) => { console.log('停止事件 (只执行一次):', data) })
myEmitter.on('error', (err) => { console.error('错误事件:', err.message) })
myEmitter.start() myEmitter.start() myEmitter.stop() myEmitter.stop()
myEmitter.emit('error', new Error('Something went wrong!'))
console.log('start事件监听器数量:', myEmitter.listenerCount('start')) console.log('所有事件名称:', myEmitter.eventNames())
myEmitter.removeAllListeners('start') console.log('移除后start事件监听器数量:', myEmitter.listenerCount('start'))
|
9. 数据库集成
概念:Node.js可以与各种数据库集成,包括MySQL、MongoDB、PostgreSQL等。
MongoDB集成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| const { MongoClient } = require('mongodb')
async function connectToMongoDB() { const client = new MongoClient('mongodb://localhost:27017') try { await client.connect() console.log('连接到MongoDB成功') const db = client.db('mydb') const collection = db.collection('users') const insertResult = await collection.insertOne({ name: '张三', email: 'zhangsan@example.com', age: 25, createdAt: new Date() }) console.log('插入结果:', insertResult.insertedId) const users = await collection.find({ age: { $gte: 18 } }).toArray() console.log('查询结果:', users) const updateResult = await collection.updateOne( { name: '张三' }, { $set: { age: 26 } } ) console.log('更新结果:', updateResult.modifiedCount) const deleteResult = await collection.deleteOne({ name: '张三' }) console.log('删除结果:', deleteResult.deletedCount) } catch (error) { console.error('MongoDB操作错误:', error) } finally { await client.close() } }
connectToMongoDB()
|
MySQL集成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| const mysql = require('mysql2/promise')
async function connectToMySQL() { const connection = await mysql.createConnection({ host: 'localhost', user: 'root', password: 'password', database: 'mydb' }) try { console.log('连接到MySQL成功') await connection.execute(` CREATE TABLE IF NOT EXISTS users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(100) UNIQUE NOT NULL, age INT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) `) const [insertResult] = await connection.execute( 'INSERT INTO users (name, email, age) VALUES (?, ?, ?)', ['张三', 'zhangsan@example.com', 25] ) console.log('插入结果:', insertResult.insertId) const [rows] = await connection.execute( 'SELECT * FROM users WHERE age >= ?', [18] ) console.log('查询结果:', rows) const [updateResult] = await connection.execute( 'UPDATE users SET age = ? WHERE name = ?', [26, '张三'] ) console.log('更新结果:', updateResult.affectedRows) const [deleteResult] = await connection.execute( 'DELETE FROM users WHERE name = ?', ['张三'] ) console.log('删除结果:', deleteResult.affectedRows) } catch (error) { console.error('MySQL操作错误:', error) } finally { await connection.end() } }
connectToMySQL()
|
10. 性能优化
概念:Node.js性能优化包括内存管理、CPU优化、I/O优化等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| const cluster = require('cluster') const os = require('os')
if (cluster.isMaster) { const numCPUs = os.cpus().length for (let i = 0; i < numCPUs; i++) { cluster.fork() } cluster.on('exit', (worker, code, signal) => { console.log(`工作进程 ${worker.process.pid} 退出`) cluster.fork() }) } else { const v8 = require('v8') v8.setFlagsFromString('--max-old-space-size=4096') setInterval(() => { const memUsage = process.memoryUsage() console.log('内存使用:', { rss: Math.round(memUsage.rss / 1024 / 1024) + ' MB', heapTotal: Math.round(memUsage.heapTotal / 1024 / 1024) + ' MB', heapUsed: Math.round(memUsage.heapUsed / 1024 / 1024) + ' MB', external: Math.round(memUsage.external / 1024 / 1024) + ' MB' }) }, 5000) if (global.gc) { setInterval(() => { global.gc() console.log('手动垃圾回收完成') }, 30000) } const NodeCache = require('node-cache') const cache = new NodeCache({ stdTTL: 600 }) function getCachedData(key) { let data = cache.get(key) if (!data) { data = { id: key, value: Math.random(), timestamp: new Date() } cache.set(key, data) console.log('数据已缓存') } else { console.log('从缓存获取数据') } return data } const mysql = require('mysql2/promise') const pool = mysql.createPool({ host: 'localhost', user: 'root', password: 'password', database: 'mydb', waitForConnections: true, connectionLimit: 10, queueLimit: 0 }) async function queryWithPool(sql, params) { const connection = await pool.getConnection() try { const [rows] = await connection.execute(sql, params) return rows } finally { connection.release() } } const compression = require('compression') const express = require('express') const app = express() app.use(compression()) app.get('/api/data', (req, res) => { const data = Array.from({ length: 1000 }, (_, i) => ({ id: i, name: `用户${i}`, email: `user${i}@example.com` })) res.json(data) }) app.listen(3000, () => { console.log(`工作进程 ${process.pid} 监听端口 3000`) }) }
|
Node.js Web框架
1. Express框架
概念:Express是Node.js最流行的Web应用框架,提供了简洁的API来构建Web应用和API。
语法规则:
- 安装:
npm install express
- 创建应用:
const app = express()
- 路由:
app.get(), app.post(), app.put(), app.delete()
- 中间件:
app.use()
- 启动服务器:
app.listen(port)
使用场景:
- RESTful API开发
- Web应用后端
- 微服务架构
- 快速原型开发
Express基本使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| const express = require('express') const app = express()
app.use(express.json()) app.use(express.urlencoded({ extended: true }))
app.use(express.static('public'))
app.get('/', (req, res) => { res.send('<h1>Hello, Express!</h1>') })
app.get('/api/users', (req, res) => { const users = [ { id: 1, name: '张三', email: 'zhangsan@example.com' }, { id: 2, name: '李四', email: 'lisi@example.com' } ] res.json(users) })
app.get('/api/users/:id', (req, res) => { const userId = parseInt(req.params.id) const user = { id: userId, name: '张三', email: 'zhangsan@example.com' } res.json(user) })
app.post('/api/users', (req, res) => { const { name, email } = req.body const newUser = { id: Date.now(), name, email } res.status(201).json(newUser) })
app.use((err, req, res, next) => { console.error(err.stack) res.status(500).json({ error: '服务器内部错误' }) })
app.use((req, res) => { res.status(404).json({ error: '页面未找到' }) })
const PORT = process.env.PORT || 3000 app.listen(PORT, () => { console.log(`Express服务器运行在 http://localhost:${PORT}`) })
|
Express中间件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| const express = require('express') const app = express()
function requestLogger(req, res, next) { console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`) next() }
function corsHandler(req, res, next) { res.header('Access-Control-Allow-Origin', '*') res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE') res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization') next() }
function authenticateToken(req, res, next) { const authHeader = req.headers['authorization'] const token = authHeader && authHeader.split(' ')[1] if (!token) { return res.status(401).json({ error: '访问令牌缺失' }) } if (token === 'valid-token') { req.user = { id: 1, name: '张三' } next() } else { res.status(403).json({ error: '无效的访问令牌' }) } }
app.use(requestLogger) app.use(corsHandler) app.use(express.json())
app.get('/api/profile', authenticateToken, (req, res) => { res.json({ user: req.user }) })
app.get('/api/admin', authenticateToken, (req, res, next) => { if (req.user.id !== 1) { return res.status(403).json({ error: '权限不足' }) } next() }, (req, res) => { res.json({ message: '管理员页面' }) })
|
Express路由模块化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| const express = require('express') const router = express.Router()
let users = [ { id: 1, name: '张三', email: 'zhangsan@example.com' }, { id: 2, name: '李四', email: 'lisi@example.com' } ]
router.get('/', (req, res) => { res.json(users) })
router.get('/:id', (req, res) => { const userId = parseInt(req.params.id) const user = users.find(u => u.id === userId) if (!user) { return res.status(404).json({ error: '用户未找到' }) } res.json(user) })
router.post('/', (req, res) => { const { name, email } = req.body if (!name || !email) { return res.status(400).json({ error: '姓名和邮箱是必需的' }) } const newUser = { id: users.length + 1, name, email } users.push(newUser) res.status(201).json(newUser) })
router.put('/: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({ error: '用户未找到' }) } const { name, email } = req.body users[userIndex] = { ...users[userIndex], name, email } res.json(users[userIndex]) })
router.delete('/: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({ error: '用户未找到' }) } users.splice(userIndex, 1) res.status(204).send() })
module.exports = router
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| const express = require('express') const userRoutes = require('./routes/users')
const app = express()
app.use(express.json()) app.use(express.urlencoded({ extended: true }))
app.use('/api/users', userRoutes)
app.get('/', (req, res) => { res.json({ message: '用户管理API' }) })
const PORT = process.env.PORT || 3000 app.listen(PORT, () => { console.log(`服务器运行在 http://localhost:${PORT}`) })
|
2. Koa框架
概念:Koa是Express团队开发的下一代Web框架,使用async/await语法,更加轻量和灵活。
语法规则:
- 安装:
npm install koa
- 创建应用:
const app = new Koa()
- 中间件:
app.use()
- 上下文:
ctx对象包含request和response
- 启动服务器:
app.listen(port)
使用场景:
- 现代Web应用
- API服务
- 微服务架构
- 需要更好的错误处理
Koa基本使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| const Koa = require('koa') const Router = require('@koa/router') const bodyParser = require('koa-bodyparser') const cors = require('@koa/cors')
const app = new Koa() const router = new Router()
app.use(cors()) app.use(bodyParser())
router.get('/', (ctx) => { ctx.body = '<h1>Hello, Koa!</h1>' })
router.get('/api/users', (ctx) => { const users = [ { id: 1, name: '张三', email: 'zhangsan@example.com' }, { id: 2, name: '李四', email: 'lisi@example.com' } ] ctx.body = users })
router.get('/api/users/:id', (ctx) => { const userId = parseInt(ctx.params.id) const user = { id: userId, name: '张三', email: 'zhangsan@example.com' } ctx.body = user })
router.post('/api/users', (ctx) => { const { name, email } = ctx.request.body const newUser = { id: Date.now(), name, email } ctx.status = 201 ctx.body = newUser })
app.use(router.routes()) app.use(router.allowedMethods())
app.on('error', (err, ctx) => { console.error('服务器错误:', err) })
const PORT = process.env.PORT || 3000 app.listen(PORT, () => { console.log(`Koa服务器运行在 http://localhost:${PORT}`) })
|
Koa中间件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| const Koa = require('koa') const app = new Koa()
async function requestLogger(ctx, next) { const start = Date.now() console.log(`${new Date().toISOString()} - ${ctx.method} ${ctx.url}`) await next() const ms = Date.now() - start console.log(`${ctx.method} ${ctx.url} - ${ms}ms`) }
async function responseTime(ctx, next) { const start = Date.now() await next() const ms = Date.now() - start ctx.set('X-Response-Time', `${ms}ms`) }
async function authenticate(ctx, next) { const token = ctx.headers.authorization?.split(' ')[1] if (!token) { ctx.status = 401 ctx.body = { error: '访问令牌缺失' } return } if (token === 'valid-token') { ctx.state.user = { id: 1, name: '张三' } await next() } else { ctx.status = 403 ctx.body = { error: '无效的访问令牌' } } }
app.use(responseTime) app.use(requestLogger)
app.use(async (ctx) => { if (ctx.path === '/') { ctx.body = '<h1>Hello, Koa!</h1>' } else if (ctx.path === '/api/profile') { await authenticate(ctx, async () => { ctx.body = { user: ctx.state.user } }) } else { ctx.status = 404 ctx.body = { error: '页面未找到' } } })
|
Koa vs Express对比
| 特性 |
Express |
Koa |
| 语法 |
回调函数 |
async/await |
| 中间件 |
线性执行 |
洋葱模型 |
| 错误处理 |
需要额外配置 |
内置try-catch |
| 学习曲线 |
相对简单 |
需要理解async/await |
| 生态系统 |
非常丰富 |
相对较少 |
| 性能 |
良好 |
更好 |
| 灵活性 |
高 |
更高 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| app.use(middleware1) app.use(middleware2) app.get('/api', handler)
app.use(async (ctx, next) => { console.log('1. 开始') await next() console.log('1. 结束') })
app.use(async (ctx, next) => { console.log('2. 开始') await next() console.log('2. 结束') })
app.use(async (ctx) => { console.log('3. 处理') ctx.body = 'Hello' })
|
3. 常用中间件
概念:中间件是处理请求和响应的函数,可以执行各种任务如身份验证、日志记录、错误处理等。
常用中间件:
cors - 跨域资源共享
helmet - 安全头设置
morgan - HTTP请求日志
compression - 响应压缩
rate-limiter - 请求频率限制
Express常用中间件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| const express = require('express') const cors = require('cors') const helmet = require('helmet') const morgan = require('morgan') const compression = require('compression') const rateLimit = require('express-rate-limit')
const app = express()
app.use(helmet())
app.use(cors({ origin: ['http://localhost:3000', 'https://yourdomain.com'], credentials: true }))
app.use(morgan('combined'))
app.use(compression())
const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100, message: '请求过于频繁,请稍后再试' }) app.use('/api/', limiter)
app.use(express.json({ limit: '10mb' })) app.use(express.urlencoded({ extended: true, limit: '10mb' }))
app.use(express.static('public'))
app.get('/api/test', (req, res) => { res.json({ message: '测试成功' }) })
app.listen(3000, () => { console.log('服务器运行在端口 3000') })
|
Koa常用中间件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| const Koa = require('koa') const Router = require('@koa/router') const bodyParser = require('koa-bodyparser') const cors = require('@koa/cors') const helmet = require('koa-helmet') const logger = require('koa-logger') const compress = require('koa-compress') const ratelimit = require('koa-ratelimit')
const app = new Koa() const router = new Router()
app.use(helmet())
app.use(cors({ origin: ['http://localhost:3000', 'https://yourdomain.com'], credentials: true }))
app.use(logger())
app.use(compress())
app.use(ratelimit({ driver: 'memory', db: new Map(), duration: 60000, errorMessage: '请求过于频繁', id: (ctx) => ctx.ip, headers: { remaining: 'Rate-Limit-Remaining', reset: 'Rate-Limit-Reset', total: 'Rate-Limit-Total' }, max: 100 }))
app.use(bodyParser({ jsonLimit: '10mb', formLimit: '10mb' }))
router.get('/api/test', (ctx) => { ctx.body = { message: '测试成功' } })
app.use(router.routes()) app.use(router.allowedMethods())
app.listen(3000, () => { console.log('服务器运行在端口 3000') })
|