【JavaScript狂补知识第④弹】Node.js
前言
Node.js这一块内容有点多,所以这篇博客可能不会一次性写完,会随着后面的学习慢慢更新……
Node.js简介
Node.js发布于2009年5月,由Ryan Dahl开发,是一个基于Chrome V8引擎的JavaScript运行环境,让JavaScript 得以运行服务端。众所周知,JavaScript也可以在浏览器中运行,如果想了解两者的区别可以通过官网的说明来了解Node.js 和浏览器之间的区别 (p2hp.com)
Node.js的用途
- 开发服务端应用:类似Java、Go等语言编写应用后端程序
- 开发工具类应用:Webpack,VIte,Babel
- 开发桌面端应用:Electron(借助Node.js开发出来的桌面应用程序框架)
Node.js通过使用核心模块和第三方模块来组织代码,下面就对常用的模块来进行学习。
fs模块
在Node.js中,文件系统(file system)模块是与文件和目录交互的核心模块之一。它提供了一系列的方法来读取、写入和管理文件,允许我们在服务器上高效地处理文件。Node.js的fs模块提供了两套API——Promise API和Callback API,下面主要讲的是Callback API,想要了解Promise API的可以前往官网文件系统 |Node.js v19 API — File system | Node.js v19 API (p2hp.com)查看
fs.writeFile(file, data[, options], callback)
异步向文件写入数据。
参数说明
- file:文件名,异步将数据写入文件,如果文件已存在,则替换该文件,若不存在则创建文件
- data:写入文件的数据,可以为string | Buffer | TypedArray | DataView
- options:配置对象,可配置encoding、mode、flag(‘w’,’a’等)
- callback:回调函数,有一个err参数,如果成功写入err为null
1 | const fs = require('fs') |
fs.writeFileSync(file, data[, options])
同步向文件写入数据。
参数说明
- file:文件名,异步将数据写入文件,如果文件已存在,则替换该文件,若不存在则创建文件
- data:写入文件的数据,可以为string | Buffer | TypedArray | DataView
- options:配置对象,可配置encoding、mode、flag(‘w’,’a’等)
1 | fs.writeFileSync('./fs-file.txt', 'fs writeFileSync\n', {flag: 'a'}) |
options对象里面的flag为’a’表示在文件末尾追加。
fs.appendFile(path, data[, options], callback)
异步追加文件内容,参数和fs.writeFile一样。
1 | fs.appendFile('./fs-file.txt', 'fs appendFile', err => { |
fs.appendFileSync(path, data[, options])
同步追加文件内容,参数和异步方法api类型大致一样,只是变成同步方法,少了回调函数。
fs.createWriteStream(path[, options])
流式写入api,适用于大文件写入或者频繁写入的场景。
参数说明
- path:文件路径
- options:配置对象(写入模式、编码等等)
返回值
fs.WriteStream对象:
- write方法写入;
- end方法是当可写流中没有更多的数据需要写入时,会触发end事件。这通常意味着所有的数据都已经成功写入,并且流已经准备好进行后续处理或关闭;
- close方法是在文件或流关闭时触发的。它不仅仅是因为没有更多的数据需要写入而触发,而是因为流或文件已经被关闭;
1 | const ws = fs.createWriteStream('./fs-file.txt', {flags: 'a'}) |
fs.readFile(path[, options], callback)
异步读取文件。
参数说明
- path:文件路径
- options:配置对象
- callback:回调函数,有err和data两个参数,如果读取成功err为null且读取的数据存放在data中为Buffer类型,如果读取失败则err不为null
1 | fs.readFile('./fs-file.txt', (err, data) => { |
fs.readFileSync(path[, options])
同步读取文件,参数相比于异步方法少了回调函数,对于读取失败可以通过try-catch捕获。
参数说明
- path:文件路径
- options:配置对象
返回值
返回文件内容(Buffer类型)
1 | try{ |
fs.createReadStream(path[, options])
流式读取api,适用于大文件读取的场景。
返回值
fs.ReadStream对象:
- 绑定data事件,每次从文件读取一块数据就触发回调函数,并把读取内容传给形参(一块数据 === 65536字节/64KB)
- 绑定end事件,文件读取完成后触发回调函数
1 | const rs = fs.createReadStream('./music/music.flac') |
fs.rename(oldPath, newPath, callback)
将 oldPath 中的文件异步重命名为作为 newPath 提供的路径名,如果newPath和oldPath目录层级不一样,则会移动文件,因此可以利用此api实现文件重命名和移动。
参数说明
- oldPath:旧文件路径,具体到文件名
- newPath:新文件路径,具体到文件名
- callback:回调函数,只有err一个参数
1 | fs.rename('./music/music.flac','./music.flac',err => { |
此方法是异步方法,同样有对应的同步方法:fs.renameSync(oldPath,newPath)
fs.unlink(path, callback)
异步删除文件或符号链接。除了可能的异常之外,不会为完成回调提供任何参数。
参数说明
- path:文件路径
- callback:回调函数
1 | fs.unlink('./music.flac',err => { |
此方法是异步方法,同样有对应的同步方法:fs.unlinkSync(path)
fs.rm(path[, options], callback)
异步删除文件和目录。除了可能的异常之外,不会为完成回调提供任何参数。与unlink不同的是,rm可以用来删除文件夹,并且提供了多种配置选项。
参数说明
- path:文件路径或者文件夹路径
- options:配置对象
- force:如果为true,如果 path 不存在,则将忽略异常。默认值:false。
- maxRetries:如果遇到 EBUSY、EMFILE、ENFILE、ENOTEMPTY 或 EPERM 错误,Node.js将重试该操作,每次尝试时retryDelay毫秒的线性回退等待。此选项表示重试次数。如果递归选项不为 true,则忽略此选项。默认值:0。
- recursive:递归选项,如果为true,则执行递归删除。在递归模式下,如果失败,将重试操作。
- retryDelay:两次重试之间等待的时间量(以毫秒为单位)。
- callback:回调函数,参数为err,成功删除则err为null
1 | fs.rm('./music', {recursive: true}, err => { |
同步方法:fs.rmdirSync(path[, options])
fs.mkdir(path[, options], callback)
异步创建目录,也可递归创建目录(递归创建需要options的recursive为true)
参数说明
- path:要创建的目录
- options:配置对象
- recursive:是否递归创建目录,默认为false
- mode:在Windows下不支持该参数
- callback:回调函数,有err和path两个参数,仅当recursive为true时才有path参数,值为递归创建的文件夹路径
1 | // 非递归创建 |
同步方法:fs.mkdirSync(path[, options])
fs.readdir(path[, options], callback)
读取目录的内容。回调获取两个参数(err、files),其中 files是目录中文件名称的数组.
参数说明
- path:文件夹路径
- options:配置对象(encoding、withFileTypes)
- callback:回调函数
1 | fs.readdir('./',{withFileTypes:true},(err, files) => { |
同步方法:fs.readdirSync(path[, options]),返回目录下文件列表
fs.stat(path[, options], callback)
获取对应path的文件/文件夹资源信息。
参数说明
- path:文件/文件夹路径
- options:配置对象
- callback:回调函数,err和stats两个参数,err为null时stats表示对应文件/文件夹的资源信息
1 | fs.stat('./fs-file.txt',(err, stats) => { |
path模块
path 模块提供了用于处理文件和目录路径的实用方法,下表是主要常用的一些方法:
API | 功能 |
---|---|
path.resolve | 拼接规范的绝对路径 |
path.sep | 获取当前操作系统的路径分隔符 |
path.parse | 解析绝对路径并返回对象 |
path.basename | 获取路径的基础名称——路径最内层名称 |
ath.dirname | 获取路径的目录名——除去路径最内层名称 |
path.extname | 获取路径的扩展名 |
对于path模块的使用还要认识以下两个特殊变量:
- __dirname:表示当前执行脚本所在的目录的绝对路径
- __filename:表示当前执行脚本的绝对路径
1 | const path = require('path') |
http模块
http 模块是 Node.js 官方提供的、用来创建 web 服务器的模块。通过 http 模块提供的http.createServer() 方法,就能方便的把一台普通的电脑,变成一台 Web 服务器,从而对外提供 Web 资源服务。下面演示了http创建web服务器的常用方法。
创建web服务器
- 引入http模块
- http.createServer()创建Server对象
- Server对象监听对应端口的请求
1 | const http = require('http'); |
通过上述代码我们创建了一个Web服务器用以监听9000端口的请求,一旦我们访问http://127.0.0.1:9000/就会向这个端口发起http请求,进而触发server的回调,web服务器就会返回字符串`NodeJS http Module`。
获取请求报文内容
http模块也为我们提供了一些api用来获取请求的相关信息,一些通用的api如下表所示:
API | 功能 |
---|---|
request.method | 获取请求的方法:GET/POST/PUT/DELETE等 |
request.url | 获取请求的路径 |
request.httpVersion | 获取http协议的版本号 |
request.headers | 获取http请求的请求头 |
对于POST请求还有请求体,可以通过绑定request的data事件来获取请求体的内容。下面是获取http请求的相关信息api的使用。
1 | const http = require('http'); |
请求路径参数解析
对于GET方法的http请求可以在url会携带一些参数,如果想要提取出来,node为我们提供了两种方式,一种是通过node内置的url模块,另一种是通过创建URL对象的方式,前一种方式因为官网说未来可能会弃用,因此下面以第二种方式为例来解析请求路径参数。
1 | const http = require('http'); |
打印的URL对象如下:
1 | URL { |
设置响应报文内容
获取请求报文之后,就要对请求做出响应,下表是设置请求报文的相关API。
API | 功能 |
---|---|
response.statusCode | 设置响应状态码 |
response.statusMessage | 设置响应信息 |
response.setHeader | 设置响应头 |
response.write | 传入字符串设置响应体信息,可以有多次调用 |
response.end | 在response.write结束后调用,同样可传信息,但是只能调用一次 |
1 | const http = require('http'); |
通过以上步骤可以制作一个简单的web服务器,但是对于一些庞大的后端项目来说就有点捉襟见肘了,后面会专门出一片博客来讲基于Node.js的Web开发应用框架——Express。