Node.js快速入门+demo案例
1. 基本介绍
node.js是js的运行环境,能够让js在后端/服务端等运行。
所以语法还是js,只是需要了解一些新的模块。
2.第一个node程序
方式一:终端输入node,在交互式界面中直接输入js代码即可
方式二:新建js文件并写入内容,终端node 文件名执行
3.基本项目结构
node使用npm进行包管理(pnpm/yarn也可以,差别不大,pnpm更快一些),安装好各种包之后会出现两个文件
package.json:记录项目相关信息及依赖的顶层包,版本号可以不精确
package-lock.json:记录项目版本及详细的依赖树,锁定精确的版本号
node_modules文件夹是下好的依赖,其余是代码文件
4.fs模块
用于文件读写。
有同步和基于promise的异步的方法,引入模块后即可调用相关的方法执行对应操作。
可以进行:文件读写、目录管理、文件状态检测、流式读取文件、其他简单操作。具体demo代码在图片中。
// fs模块使用方式
// Promise API
// 引入fs/promises模块m
const fs = require('fs/promises');
// 传统回调/同步api
const fsCallback = require('fs');
const fsSync = require('fs')
// =======================
// 1. 读写文件
// =======================
async function handleFile() {
// 覆盖写文件
await fs.writeFile('demo.txt', 'hello, node.js!', 'utf8');
// 追加写文件
await fs.appendFile('demo.txt', '\nNew line append.', 'utf8');
// 读文件内容
const content = await fs.readFile('demo.txt', 'utf8');
console.log(content);
}
// =======================
// 2. 目录管理
// =======================
async function handleDirectory() {
// 新建目录
await fs.mkdir('folder/path', { recursive: true });
// 读取路径下所有文件,返回fs.Dirent数组
const entries = await fs.readdir('./', { withFileTypes: true });
for (const entry of entries) {
console.log(`${entry.name} -> ${entry.isDirectory() ? 'DIR' : 'FILE'}`);
}
// 删除目录,recursive递归删除,force忽略不存在错误
await fs.rm('folder', { recursive: true, force: true });
}
// ======================
// 3. 文件状态检测
// ======================
const { constants } = require('fs')
async function inspectFile(path) {
// access进行可访问性权限检查,检查成功继续执行,检查失败(文件不存在/无权限)抛出错误
// |是按位或,代表把两个权限打包,而不是任一满足即可
await fs.access(path, constants.F_OK | constants.R_OK);
// 返回一个fs.Stats实例,包含状态信息
const stats = await fs.stat(path);
console.log('size: ', stats.size);
console.log('Is file: ', stats.isFile());
console.log('Created time: ', stats.birthtime);
}
// =========================
// 4. 流式读取文件,利用pipeline,可以自动处理错误与资源清理
// =========================
const { pipeline } = require('stream/promises');
await pipeline(
fs.createReadStream('large_souce.log'),
fs.createWriteStream('copy_file.log')
);
// ======================
// 5. 其他操作
// ======================
// 文件重命名
fs.rename('old_name.txt', 'new_name.txt');
// 删除文件
fs.unlink('new_name.txt');
handleFile();
handleDirectory();
inspectFile('server.js')
5.http模块
可以处理http客户端/服务端请求。
引入模块后即可自己启动本地服务/向远程url发送请求。
两个核心对象,req(request)是客户端发送的请求对象,res(response)是服务端返回的响应对象。
本地服务构建流程:创建http服务,启动并监听http服务,可以自定义res的内容。
向远程url发送请求可以自定义req,但只能监听res返回内容。
// 创建一个基础的http服务
// 使用 CommonJS 规范的 require() 函数导入 Node.js 内置模块
const http = require('http');
// ===========================
// 1.自己启动本地服务
// ===========================
// 用http模块中的方法创建一个http服务,接收一个回调函数作为收到请求时的响应
// 仅是创建,并没有启动
// req: request可读流,客户端发来的请求
// req.method http方法
// req.url 请求路径及查询参数
// req.headers 请求头对象
// res:response可写流,服务器返回的请求
// res.writeHead 显式写入状态吗与响应头
// res.setHeader 设置单个响应头
// res.write 向客户端发送一块数据
// res.end 完成响应并关闭连接,必须使用
const server = http.createServer((req, res) => {
const { method, url } = req;
console.log(`method: ${method}, url: ${url}`);
// 因为是本地启动的服务,所以可以自己写服务返回内容
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
res.end('你好,这是我的第一个 Node.js 服务器!\n');
});
// 启动并监听3000端口,服务启动则执行回调
// 可自行打开 localhost:3000 查看返回结果
const PORT = 3000;
server.listen(PORT, () => {
console.log(`服务已启动:http://localhost:${PORT}`);
});
// ==========================
// 2.向远程url发送请求
// ==========================
const req = http.get("http://jsonplaceholder.typicode.com/todos/1", (res) => {
let rawData = '';
// 监听服务器返回的内容
res.on('data', (chunk) => {
rawData += chunk;
})
res.on('end', () => {
const parsedData = JSON.parse(rawData);
console.log('服务器返回的数据为:', parsedData);
})
})
// 监听请求发送情况
req.on('error', (err) => {
console.error(`Request failed, ${err.message}`)
})
6.express框架
6.1 基本用法:引入express库,定义请求体解析中间件,定义接口,启动服务并监听
6.2 中间件:
有req,res,next的被叫做是中间件,其实就是一个函数,可以自定义放行(next)逻辑
使用方式一:全局注册并使用中间件app.use
使用方式二:自定义中间件并挂载到合适的路由使用
6.3模块化路由:
类似vue,可以在子代文件中定义细路由并导出,亲代文件中引入并注册挂载到对应大路由
// express框架
// ======================
// express框架基本用法
// ======================
// 1. 引入express库
const express = require('express');
// 2. 创建express应用实例
const app = express();
const PORT = 3000;
// 3. 注册请求体解析中间件,req的请求体会被自动转换为js对象绑定到req.json上
app.use(express.json());
// 4. 定义get接口
app.get('/', (req, res) => {
// 向客户端发送信息,并结束本次请求响应
res.send('Hello, Express');
});
// 定义get接口,id为占位符(带冒号表示放进来的是变量的值)
app.get('/user/:id', (req, res) => {
const userId = req.params.id;
// 设置响应头,同时内容转为json格式的字符串发送给客户端
res.json({ id: userId, name: 'Alice' });
});
// 定义post请求
app.post('/users', (req, res) => {
const user = req.body;
// 定义返回的状态码,同时链式定义返回的json字符串
res.status(201).json({ message: 'user created', data: user });
})
// 5. 启动服务在PORT端口上并监听
app.listen(PORT, () => {
console.log(`服务正在运行,端口号为${PORT}`);
})
// ========================
// 中间件
// ========================
// a. 全局注册中间件并使用
// 有req,res,next的被叫做是中间件,其实就是一个函数,可以自定义放行(next)逻辑
app.use((req, res, next) => {
console.log('...');
next();
})
// b1. 定义鉴权中间件
function authGuard(req, res, next) {
const token = req.headers['authorization'];
if (token) {
next();
} else {
// 中间件进行拦截并响应,设置状态码,返回json字符串
res.status(401).json({ error: 'Unauthorized' })
}
}
// b2. 使用authGuard中间件,用.send/.json方法就会自动结束本次请求响应,不用手动next
app.get('/dashboard', authGuard, (req, res) => {
res.send('welcome');
})
// c. 多中间件链式组合
// validateParams也是一个中间件,这里没有实现,只是占位表示一下
app.post('/profile', validateParams, authGuard, (req, res) => {
res.send('Profile Updated');
})
// =======================
// 模块化路由
// =======================
// a1. ./routes/userRoutes
// 子文件中使用路由封装组件
const router = express.Router();
// a2. 子文件中定义get接口
router.get('/', (req, res) => res.send('User List'));
router.get('/:id', (req, res) => res.send(`User ${req.params.id}`));
// a3. 子文件中导出路由接口
module.exports = router;
// b1. 亲代文件中引入子路由
const userRouter = require('./routes/userRoutes');
// b2. 亲代文件中注册子路由,把对应的url重定向过去
app.use('/api/users', userRouter);
更多推荐


所有评论(0)