Nodejs模块
Nodejs模块
首先对比一下浏览器中的JavaScript与Nodejs中的JavaScript
Nodejs中的JavaScript是不能操作DOM跟BOM
Buffer(缓冲器)
概念
Buffer 是一个类似于数组的对象 ,用于表示固定长度的字节序列
Buffer 本质是一段内存空间,专门用来处理二进制数据
特点
- Buffer 大小固定且无法调整
- Buffer 性能较好,可以直接对计算机内存进行操作
- 每个元素的大小为1字节(byte)=8个二进制位(bit)
使用
- 创建Buffer
// 创建了一个长度为 10 字节的 Buffer,相当于申请了 10 字节的内存空间,每个字节的值为 0
let buf_1 = Buffer.alloc(10); // 结果为 <Buffer 00 00 00 00 00 00 00 00 00 00>
// 创建了一个长度为 10 字节的 Buffer,buffer 中可能存在旧的数据, 可能会影响执行结果,所以叫unsafe
// 直接内存
let buf_2 = Buffer.allocUnsafe(10);
//通过字符串创建 Buffer
let buf_3 = Buffer.from('hello');
//通过数组创建 Buffer
let buf_4 = Buffer.from([105, 108, 111, 118, 101, 121, 111, 117]);
-
Buffer 与字符串的转化
我们可以借助toString
方法将Buffer
转为字符串let buf_4 = Buffer.from([105, 108, 111, 118, 101, 121, 111, 117]); console.log(buf_4.toString())
toString 默认是按照 utf-8 编码方式进行转换的。
-
Buffer 的读写
Buffer可以直接通过[]
的方式对数据进行处理。//读取 console.log(buf_3[1]); //修改 buf_3[1] = 97; //查看字符串结果 console.log(buf_3.toString());
注意:
- 如果修改的数值超过255,则超过8位数据会被舍弃
- 一个utf-8的字符一般占3个字节
fs模块
fs全称为file system,称之为文件系统 ,是Node.js中的内置模块,可以对计算机中的磁盘进行操作。
fs模块可以对文件进行如下一些个操作:
- 文件写入
- 文件读取
- 文件移动与重命名
- 文件删除
- 文件夹操作
- 查看资源状态
- ...
文件写入
文件写入就是将数据保存到文件中,我们可以使用如下几个方法来实现该效果
方法 | 说明 |
---|---|
writeFile | 异步写入 |
writeFileSync | 同步写入 |
appendFile/appendFileSync | 追加写入 |
createWriteStream | 流式写入 |
writeFile异步写入
语法:fs.writeFile(file, data, [options], callback)
参数说明:
- file 文件名
- data 待写入的数据
- options 选项设置 (可选)
- callback 写入回调
返回值: undefined
代码示例:
// require 是 Node.js 环境中的'全局'变量,用来导入模块
const fs = require('fs');
//将 『三人行,必有我师焉。』 写入到当前文件夹下的『座右铭.txt』文件中
fs.writeFile('./座右铭.txt', '三人行,必有我师焉。', err => {
//如果写入失败,则回调函数调用时,会传入错误对象,如写入成功,会传入 null
if(err) {
console.log(err);
return;
}
console.log('写入成功');
});
writeFileSync同步写入
语法:fs.writeFileSync(file, data, [options])
参数与writeFile
大体一致,只是没有callback
参数
返回值:undefined
代码示例:
try{
fs.writeFileSync('./座右铭.txt', '三人行,必有我师焉。');
}catch(e){
console.log(e);
}
Node.js中的磁盘操作是由其他线程完成的,结果的处理有两种模式:
- 同步处理
JavaScript
主线程会等待其他线程的执行结果,然后再继续执行主线程的代码,效率较低- 异步处理
JavaScript
主线程不会等待其他线程的执行结果,直接执行后续的主线程代码,效率较好
appendFile/appendFileSync追加写入
appendFile
作用是在文件尾部追加内容,appendFile
语法与writeFile
语法完全相同
语法:
fs.appendFile(file, data, [options], callback)
fs.appendFileSync(file, data, [options])
返回值:二者都为undefined
实例代码:
fs.appendFile('./座右铭.txt','择其善者而从之,其不善者而改之。', err => {
if(err) throw err;
console.log('追加成功');
});
fs.appendFileSync('./座右铭.txt','\r\n温故而知新, 可以为师矣');
createWriteStream流式写入
语法:fs.createWriteStream(path, [options])
参数说明:
- path 文件路径
- options 选项配置(可选)
返回值:Object
代码示例:
let ws = fs.createWriteStream('./观书有感.txt');
ws.write('半亩方塘一鉴开\r\n');
ws.write('天光云影共徘徊\r\n');
ws.write('问渠那得清如许\r\n');
ws.write('为有源头活水来\r\n');
ws.end();
程序打开一个文件是需要消耗资源的,流式写入可以减少打开关闭文件的次数。
流式写入方式适用于大文件写入或者频繁写入的场景,writeFile
适合于写入频率较低的场景
写入文件的场景
文件写入在计算机中是一个非常常见的操作,下面的场景都用到了文件写入
- 下载文件
- 安装软件
- 保存程序日志,如 Git
- 编辑器保存文件
- 视频录制
当需要持久化保存数据的时候,应该想到文件写入
文件读取
文件读取,就是通过程序从文件中取出其中的数据,我们可以使用如下几种方式:
方法 | 说明 |
---|---|
readFile | 异步读取 |
readFileSync | 同步读取 |
createReadStream | 流式读取 |
readFile异步读取
语法:fs.readFile(path, [options], callback)
参数说明:
- path 文件路径
- options 选项配置
- callback 回调函数
返回值:undefined
代码示例:
//导入 fs 模块
const fs = require('fs');
fs.readFile('./座右铭.txt', (err, data) => {
if(err) throw err;
console.log(data);
});
// 指定编码方式读取
fs.readFile('./座右铭.txt', 'utf-8',(err, data) => {
if(err) throw err;
console.log(data);
});
readFileSync同步读取
语法:fs.readFileSync(path, [options])
参数说明:
- path 文件路径
- options 选项配置
返回值:string | Buffer
代码示例:
// 此时返回的是 Buffer
let data = fs.readFileSync('./座右铭.txt');
// 设置了编码方式,将Buffer按utf-8方式转换成 string
let data2 = fs.readFileSync('./座右铭.txt', 'utf-8');
createReadStream流式读取
语法:fs.createReadStream(path, [options])
参数说明:
- path 文件路径
- options 选项配置(可选)
返回值:Object
代码示例:
//创建读取流对象
let rs = fs.createReadStream('./观书有感.txt');
//每次取出 64k 数据后执行一次 data 回调
rs.on('data', data => {
console.log(data);
console.log(data.length);
});
//读取完毕后, 执行 end 回调
rs.on('end', () => {
console.log('读取完成')
})
读取文件应用场景
- 电脑开机
- 程序运行
- 编辑器打开文件
- 查看图片
- 播放视频
- 播放音乐
- Git 查看日志
- 上传文件
- 查看聊天记录
- ...
文件移动与重命名
在Node.js
中,我们可以使用rename
或renameSync
来移动或重命名文件或文件夹
语法:
fs.rename(oldPath, newPath, callback)
fs.renameSync(oldPath, newPath)
参数说明:
- oldPath 文件当前的路径
- newPath 文件新的路径
- callback 操作后的回调
代码示例:
// 异步回调方式
fs.rename('./观书有感.txt', './论语/观书有感.txt', (err) =>{
if(err) throw err;
console.log('移动完成')
});
// 同步方式
fs.renameSync('./座右铭.txt', './论语/我的座右铭.txt');
文件删除
在Node.js
中,我们可以使用unlink
或unlinkSync
来删除文件
语法:
fs.unlink(path, callback)
fs.unlinkSync(path)
参数说明:
- path 文件路径
- callback 操作后的回调
代码示例:
fs.unlink('./test.txt', err => {
if(err) throw err;
console.log('删除成功');
});
fs.unlinkSync('./test2.txt');
文件夹操作
借助Node.js
的能力,我们可以对文件夹进行创建、读取、删除等操作
方法 | 说明 |
---|---|
mkdir / mkdirSync | 创建文件夹 |
readdir / readdirSync | 读取文件夹 |
rmdir / rmdirSync | 删除文件夹 |
创建文件夹
在Node.js
中,我们可以使用mkdir
或mkdirSync
来创建文件夹
语法:
fs.mkdir(path[, options], callback)
fs.mkdirSync(path[, options])
参数说明:
- path 文件夹路径
- options 选项配置(可选)
- callback 操作后的回调
示例代码:
//异步创建文件夹
fs.mkdir('./page', err => {
if(err) throw err;
console.log('创建成功');
});
//递归异步创建
fs.mkdir('./1/2/3', {recursive: true}, err => {
if(err) throw err;
console.log('递归创建成功');
});
//递归同步创建文件夹
fs.mkdirSync('./x/y/z', {recursive: true});
读取文件夹
在Node.js
中,我们可以使用readdir
或readdirSync
来读取文件夹
语法:
fs.readdir(path[, options], callback)
fs.readdirSync(path[, options])
参数说明:
- path 文件夹路径
- options 选项配置(可选)
- callback 操作后的回调
示例代码:
//异步读取
fs.readdir('./论语', (err, data) => {
if(err) throw err;
console.log(data);
});
//同步读取
let data = fs.readdirSync('./论语');
console.log(data);
删除文件夹
在Node.js
中,我们可以使用rmdir
或rmdirSync
来删除文件夹
语法:
fs.rmdir(path[, options], callback)
fs.rmdirSync(path[, options])
参数说明:
- path 文件夹路径
- options 选项配置(可选)
- callback 操作后的回调
示例代码:
//异步删除文件夹
fs.rmdir('./page', err => {
if(err) throw err;
console.log('删除成功');
});
//异步递归删除文件夹
fs.rmdir('./1', {recursive: true}, err => {
if(err) {
console.log(err);
}
console.log('递归删除')
});
//同步递归删除文件夹
fs.rmdirSync('./x', {recursive: true})
查看资源状态
在Node.js
中,我们可以使用stat
或statSync
来查看资源的详细信息
语法:
fs.stat(path[, options], callback)
fs.statSync(path[, options])
参数说明:
- path 文件夹路径
- options 选项配置( 可选 )
- callback 操作后的回调
示例代码:
//异步获取状态
fs.stat('./data.txt', (err, data) => {
if(err) throw err;
console.log(data);
});
//同步获取状态
let data = fs.statSync('./data.txt');
console.log(data);
结果值对象结构:
- size 文件体积
- birthtime 创建时间
- mtime 最后修改时间
- isFile 检测是否为文件
- isDirectory 检测是否为文件夹
- ....
相对路径问题
fs模块对资源进行操作时,路径的写法有两种:
- 相对路径
./座右铭.txt
当前目录下的座右铭.txt座右铭.txt
等效于上面的写法../座右铭.txt
当前目录的上一级目录中的座右铭.txt
- 绝对路径
D:/Program Files
windows系统下的绝对路径/usr/bin
Linux系统下的绝对路径
相对路径中所谓的当前目录,指的是命令行的工作目录,而并非是文件的所在目录
所以当命令行的工作目录与文件所在目录不一致时,会出现一些BUG
__dirname
__dirname
与require
类似,都是Node.js
环境中的'全局'变量
__dirname
保存着当前文件所在目录的绝对路径,可以使用__dirname
与文件名拼接成绝对路径
代码示例:
let data = fs.readFileSync(__dirname + '/data.txt');
console.log(data);
使用
fs
模块的时候,尽量使用__dirname
将路径转化为绝对路径,这样可以避免相对路径产生的Bug
path模块
path模块提供了操作路径的功能,如下几个较为常用的几个API:
API | 说明 |
---|---|
path.resolve | 拼接规范的绝对路径常用 |
path.sep | 获取操作系统的路径分隔符 |
path.parse | 解析路径并返回对象 |
path.basename | 获取路径的基础名称 |
path.dirname | 获取路径的目录名 |
path.extname | 获得路径的扩展名 |
代码示例:
const path = require('path');
//获取路径分隔符
console.log(path.sep);
//拼接绝对路径
console.log(path.resolve(__dirname, 'test'));
//解析路径
let pathname = 'D:/program file/nodejs/node.exe';
console.log(path.parse(pathname));
//获取路径基础名称
console.log(path.basename(pathname));
//获取路径的目录名
console.log(path.dirname(pathname));
//获取路径的扩展名
console.log(path.extname(pathname));
http模块
在学习http模块之前需要先了解HTTP协议
使用nodejs创建HTTP服务
操作步骤
//1. 导入 http 模块
const http = require('http');
//2. 创建服务对象 create 创建 server 服务
// http.createServer 里的回调函数的执行时机: 当接收到 HTTP 请求的时候,就会执行
// request 意为请求. 是对请求报文的封装对象, 通过 request 对象可以获得请求报文的数据
// response 意为响应. 是对响应报文的封装对象, 通过 response 对象可以设置响应报文
const server = http.createServer((request, response) => {
response.end('Hello HTTP server');
});
//3. 监听端口, 启动服务
server.listen(9000, () => {
console.log('服务已经启动, 端口 9000 监听中...');
});
测试
浏览器请求对应端口 http://127.0.0.1:9000
注意事项
- 命令行 ctrl + c 停止服务
- 当服务启动后,更新代码 必须重启服务才能生效
- 响应内容中文乱码的解决办法
response.setHeader('content-type','text/html;charset=utf-8');
- 端口号被占用
Error: listen EADDRINUSE: address already in use :::9000
关闭当前正在运行监听端口的服务(使用较多)
修改其他端口号 - HTTP协议默认端口是80。HTTPS协议的默认端口是443, HTTP服务开发常用端口有3000808080909000等
如果端口被其他程序占用,可以使用 资源监视器 找到占用端口的程序,然后使用 任务管理器 关闭对应的程序
获取HTTP请求报文
想要获取请求的数据,需要通过request
对象
含义 | 语法 | 重点掌握 |
---|---|---|
请求方法 | request.method | * |
请求版本 | request.httpVersion | |
请求路径 | request.url | * |
URL路径 | require('url').parse(request.url).pathname | * |
URL查询字符串 | require('url').parse(request.url, true).query | * |
请求头 | request.headers | * |
请求体 | request.on('data', function(chunk){}) request.on('end', function(){}); |
注意事项:
request.url
只能获取路径以及查询字符串,无法获取URL
中的域名以及协议的内容request.headers
将请求信息转化成一个对象,并将属性名都转化成了『小写』- 关于路径:如果访问网站的时候,只填写了
IP
地址或者是域名信息,此时请求的路径为『/』 - 关于
favicon.ico
:这个请求是属于浏览器自动发送的请求
搭建HTTP服务示例
//1、引入http模块
const http = require("http");
//2、建立服务
const server = http.createServer((request,response)=>{
let {url,method} = request; //对象的解构赋值
//设置响应头信息
//解决中文乱码
response.setHeader("Content-Type","text/html;charset=utf-8")
if(url == "/register" && method == "GET"){
response.end("注册页面");
}else if(url=="/login" && method == "GET"){
response.end("登录页面");
}else{
response.end("<h1>404 Not Found</h1>")
}
})
//3、监听端口
server.listen(8000,()=>{
console.log('服务启动中....');
})
设置HTTP响应报文
作用 | 语法 |
---|---|
设置响应状态码 | response.statusCode |
设置响应状态描述 | response.statusMessage ( 用的非常少 ) |
设置响应头信息 | response.setHeader('头名', '头值') |
设置响应体 | response.write('xx') response.end('xxx') |
write和end的两种使用情况:
//1. write 和 end 的结合使用 响应体相对分散
response.write('xx');
response.write('xx');
response.write('xx');
response.end(); //每一个请求,在处理的时候必须要执行 end 方法的
//2. 单独使用 end 方法 响应体相对集中
response.end('xxx');
资源类型(mime类型)
媒体类型(通常称为 Multipurpose Internet Mail Extensions 或 MIME 类型 )是一种标准,用来表示文档、文件或字节流的性质和格式。
mime 类型结构:[type]/[subType]
例如:text/html text/css image/jpeg image/png application/json
HTTP服务可以设置响应头Content-Type
来表明响应体的MIME
类型,浏览器会根据该类型决定如何处理资源
下面是常见文件对应的mime
类型
let mimes = {
html: 'text/html',
css: 'text/css',
js: 'text/javascript',
png: 'image/png',
jpg: 'image/jpeg',
gif: 'image/gif',
mp4: 'video/mp4',
mp3: 'audio/mpeg',
json: 'application/json',
other: 'application/octet-stream'
}
对于未知的资源类型,可以选择
application/octet-stream
类型,浏览器在遇到该类型的响应时,会对响应体内容进行独立存储,也就是我们常见的下载效果
GET和POST请求的区别
GET
和POST
是HTTP
协议请求的两种方式
GET
主要用来获取数据POST
主要用来提交数据GET
带参数请求是将参数缀到URL
之后,在地址栏中输入url
访问网站就是GET
请求,POST
带参数请求是将参数放到请求体中POST
请求相对GET
安全一些,因为在浏览器中参数会暴露在地址栏GET
请求大小有限制,一般为2K
,而POST
请求则没有大小限制GET
请求是幂等的POST
不是幂等的
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异