目录
一、初识Node.js
1、简介
Node.js 是一个基于Chrome V8引擎的 JavaScript 运行时(运行环境)。
官方地址
Node.js的核心部分是V8引擎和内置API,只不过该内置API不包括浏览器内置的API如DOM、BOM等,它包括fs、path、http、JS内置对象、querystring等。
注意:浏览器是JavaScript的前端运行环境,而Node.js 是 JavaScript 的后端运行环境。另外,在Node.js中无法调用DOM和BOM等浏览器内置API。
2、作用
①基于Express框架—Express官方文档,可以快速构建 Web应用;
②基于Electron框架—Electron官方文档,可以构建跨平台的桌面应用;
③基于restify框架—restify官方文档,可以快速构建API接口项目;
④读写和操作数据库、创建实用的命令行工具辅助前端开发等。
3、安装
点击官方地址下载左边LTS版本即可,当然也可以选择右边尝鲜版,不过可能会有小bug。下载后一路傻瓜式安装即可。
测试安装Node.js是否成功,使用win+R打开终端输入命令node -v
,能够返回版本号即安装成功。另外,Node.js中自带npm(Node Package Manager,是一个Node.js包管理和分发工具),可以通过npm -v
指令查看当前版本。
4、在node.js中运行js
①打开终端;②输入命令node [要执行的js文件的位置]
。
简便方法:在外部文件夹中打开要运行的js文件的位置,在空白区域按住shift
+鼠标右键
即可选择在此处打开Powershell窗口(s),然后直接输入命令node [js文件名]
即可运行。
注意:在 Windows 的powershell或cmd终端中,可以通过以下快捷键来提高终端的操作效率:
①使用⬆键,可以快速定位到上一次执行的命令;
②使用tab键,能够快速补全路径;
③使用esc键,能够快速清空当前已输入的命令;
④输入cls命令,可以清空终端。
二、fs文件系统模块(重要)
fs模块是Node.js官方提供的、用来操作文件的模块。它提供了一系列的方法和属性,用来满足用户对文件的操作需求。例如fs.readFile()
方法用来读取指定文件中的内容,fs.writeFile()
方法用来向指定的文件中写入内容。如果要在Js代码中使用fs模块来操作文件,则需要使用如下的方式先导入它(ES6模块化思想):
const fs = require('fs')
常见的API及官方文档
查看其它fs.chmod()等:Node.js文件系统模块
读写文件
1、fs.readFile()与fs.readFileSync()
在 Node.js中读取文件最简单的方式是使用fs.readFile()
方法,另外,也可以使用同步的版本fs.readFileSync()
。fs.readFile() 和 fs.readFileSync() 都会在返回数据之前将文件的全部内容读取到内存中。使用fs.readFile()
方法可以读取指定文件中的内容,语法格式如下:
//path∶必选参数,字符串,表示文件的路径;
//[option]:可选参数,表示以什么编码格式来读取文件;
//callback:必选参数,文件读取完成后,通过回调函数拿到读取的结果。
fs.readFile(path[,options], callback) //语法格式
//判断文件是否读取成功
const fs = require('fs')
//如果读取成功,则err的值为null,datastr的值为文件的内容;
//如果读取失败,则err的值为错误对象,datastr的值为undefined
fs.readFile('[文件路径]',"utf8",function(err, dataStr){ //该[文件路径]是相对于js文件的路径
}
//判断读取文件是否成功
//如果读取成功,则err的值为null,datastr的值为文件的内容;
//如果读取失败,则err的值为错误对象,datastr的值为undefined
fs.readFile('[文件路径]',"utf8",function(err, result){
if(err){ //err为真则返回错误信息
return console.log( '文件读取失败!' + err.message))
}
console.log('文件读取成功,内容是: ' + result)
})
//同步读取文件
const fs = require('fs')
try{
const data = fs.readFileSync('[文件路径]', 'utf8')
console.log(data)
}catch(err) {
console.error(err)
}
2、fs.writeFile()与fs.writeFileSync()
在 Node.js 中写入文件最简单的方式是使用fs.writeFile()
API,也可以使用同步的版本 fs.writeFileSync()
。注意:fs.writeFileSync()
API 会替换文件的内容(如果文件已经存在)。使用fs.writeFile()
方法可以向指定文件中写入内容,语法格式如下:
//file∶必选参数,字符串,表示文件的路径;
//data:必选参数,表示要写入的内容;
//[option]:可选参数,表示以什么格式来写入文件内容,默认值是utf-8;
//callback:必选参数,文件写入完成后,通过回调函数拿到读取的结果。
fs.writeFile(file,data[,options], callback) //语法格式
//判断文件是否写入成功
const fs = require('fs')
fs.readFile('[文件路径]',"[内容]",function(err){ //该[文件路径]是相对于js文件的路径
//如果写入成功,err值为null;写入失败则是一个错误对象
if(err){ //err为真则返回错误信息
return console.log( '文件写入失败!' + err.message))
}
console.log('文件写入成功!')
})
注意:fs.writeFile()
方法只能用来创建文件,不能用来创建路径。且重复调用fs.writeFile()写入同一个文件,新写入的内容会覆盖之前的旧内容。
2.1 文件追加写入
将内容追加到文件末尾的便捷方法是fs.appendFile()
及其对应的fs.appendFileSync()
方法。
2.2 文件拷贝写入
const fs = require("fs");
//同步拷贝copyFilesync
fs.copyFileSync("demo.txt", "newdemo.txt");
let data = fs.readFileSync("newdemo.txt", "utf8");
console.log(data);
//异步拷贝copyFile
fs.copyFile("demo.txt", "newdemo.txt", () => {
fs.readFile("newdemo.txt", "utf8", (err, data) =>{
console.log(data);
});
})
2.3 使用流
所有这些方法都是在将全部内容写入文件之后才会将控制权返回给程序(在异步的版本中,这意味着执行回调)。
3、路径动态拼接
在使用fs模块操作文件时,如果提供的操作路径是以/
或../
开头的相对路径时,很容易出现路径动态拼接错误的问题。原因:代码在运行的时候,会以执行node命令时所处的目录,动态拼接出被操作文件的完整路径。
解决方法①:在使用fs模块操作文件时,直接提供完整的路径(绝对路径),不要提供/
或../
开头的相对路径,从而防止路径动态拼接的问题。缺点:移植性差,不利于维护。
解决方法②:使用__dirname
,dirname表示当前文件所在的位置。
//该[文件路径]是相对于js文件的路径
fs.readFile(__dirname + '[文件路径]',"utf8",function(err, dataStr){
console.log(err)
console.log(dataStr)
}
使用文件夹
地址:在 Node.js 中使用文件夹
它包括检查文件夹是否存在fs.access()
方法、创建新的文件夹fs.mkdir()
或fs.mkdirSync()
方法、读取目录的内容fs.readdir()
或fs.readdirSync()
方法以及重命名、删除文件夹等操作及对应方法。
三、path路径模块(重要)
path模块是Node.js官方提供的、用来处理路径的模块。它提供了一系列的方法和属性,用来满足用户对路径的处理需求。例如path.join()
方法用来将多个路径片段拼接成一个完整的路径字符串,path.basename()
方法用来从路径字符串中将文件名解析出来。如果要在Js代码中使用fs模块来操作文件,则需要使用如下的方式先导入它:
const path = require('path')
常见的API及官方文档
查看其它path.relative()等:Node.js路径模块
1、path.join()
使用path.join()
方法可以将多个路径片段拼接成一个完整的路径字符串,语法格式如下:
//...path:<string> 路径片段的序列
//返回值:<string>
path.join([...paths]) //语法格式
// ../会抵消前面一个路径
const pathStr = path.join('/a', '/b/c', '../', '/d', 'e')
console.log(pathStr) // /a/b/d/e
const pathStr2 = path.join(__dirname, '[文件路径]')
console.log(pathStr2) // '当前文件所处目录/[文件路径]'
注意:今后凡是涉及到路径拼接的操作,都要使用path.join()
方法进行处理,不要直接使用+
进行字符串的拼接(如fs模块的路径拼接问题)。
2、path.basename()
使用path.basename()
方法用来从路径字符串中(获取路径中的最后一部分)将文件名解析出来,语法格式如下:
//path:<string> 必选参数,表示一个路径的字符串;
//ext:<string> 可选参数,表示文件扩展名;
//返回:<string> 表示路径中的最后一部分
path.basename(path[, ext]) //语法格式
//eg:
const path = require('path')
const fpath = 'abc/efg/index.html';
let fullName = path.basename(fpath)
console.log(fullName) //index.html
// 如果有ext参数则只会返回文件名,而不会返回扩展名
let namewithoutExt = path.basename(fpath, ".html")
console.log(namewithoutExt) //index
3、path.extname()
使用path.extname()
方法,可以获取路径中的扩展名部分:
const path = require('path')
const fpath = '/abc/efg/index.html'
const fext = path.extname(fpath)
console.log(fext) //.html
四、http模块(重要)
http模块是 Node.js官方提供的、用来创建web服务器的模块。官方文档链接:Node.js—Http模块
通过http模块提供的 http.createServer()
方法,就能方便的把一台普通的电脑,变成一台Web服务器,从而对外提供 Web 资源服务。如果要希望使用http模块创建Web服务器,则需要先导入它:
//导入http模块
const http = require('http')
1、创建基本的web服务器
//1、导入http模块
const http = require('http')
//2、调用http.createServer()方法创建web服务器实例
const server = http.createServer()
//3、为服务器实例绑定request事件,监听客户端的请求
server.on('request', (req,res) => {})
//4、调用server.listen(端口号,回调函数)方法,即可启动web服务器
server.listen(8080,function (){
console.log('server running at http://127.0.0.1:8080')
})
request事件的req
和res
属性介绍:
server.on('request', (req,res) => {
//req是请求对象,它包含了与客户端相关的数据和属性
//req.url是客户端请求的URL地址
//注意:该请求地址是从端口号开始的后面的地址,而不是完整的地址
const url = req.url
//req.method是客户端的method请求类型
const method = req.method
const str = 'Your request url is $(ur1),and request method is ${method)'
console.log(str)
//res是响应对象,它包含了与服务器相关的数据和属性
//要发送到客户端的字符串
const str = 'Your request url is ${req.url},and request method is ${req.method}'
//为了防止中文显示乱码的问题,需要设置响应头Content-Type的值为'text/html,charset=utf-8'
res.setHeader('Content-Type', 'text/html; charset=utf-8')
//res.end()方法的作用是:向客户端发送指定的内容,并结束这次请求的处理过程
res.end(str)
})
2、根据url响应对应的html内容
动态响应内容:
server.on('request', (req,res) => {
const url = req.url
let content = '<h1>404 Not found!</h1>' //设置默认的内客为404 Not found
if(url === '/' || url === '/index.html'){
content = '<h1>首页</h1>'
}else if(url === '/about.html'){
content = '<h1>关于页面</h1>'
}
res.setHeader('Content-Type', 'text/html; charset=utf-8')
res.end(content)
})
五、os模块
文档地址:Node.js 操作系统模块
该模块提供了许多函数,可用于从底层的操作系统和程序运行所在的计算机上检索信息并与其进行交互。有一些有用的属性可以告诉我们一些与处理文件有关的关键事项。
六、events模块
文档地址:Node.js 事件模块
事件模块为提供了EventEmitter
类,这是在 Node.js 中处理事件的关键。它包括一系列方法。
七、Node.js Buffer
Buffer
是内存区域。它表示在V8 JavaScript 引擎外部分配的固定大小的内存块(无法调整大小)。可以将buffer视为整数数组
,每个整数代表一个数据字节,它由 Node.js Buffer类
实现。。Buffer被引入用以帮助开发者处理二进制数据,在此生态系统中传统上只处理字符串而不是二进制数据。Buffer与流紧密相连,当流处理器接收数据的速度快于其消化的速度时,则会将数据放入buffer中。比如:一个简单的场景是:当观看YouTube视频时,红线超过了观看点:即下载数据的速度比查看数据的速度快,且浏览器会对数据进行缓冲。
1、创建 buffer
可以使用Buffer.from()
、Buffer.alloc()
和Buffer.allocUnsafe()
方法。
const buf = Buffer.from('Hey!') //方法①
//也可以只初始化 buffer(传入大小)
//const buf = Buffer.alloc(1024) //方法②
//const buf = Buffer.allocUnsafe(1024) //方法③
alloc
和allocUnsafe
的区别:虽然 alloc 和 allocUnsafe 均分配指定大小的 Buffer(以字节为单位),但是 alloc 创建的 Buffer 会被使用零进行初始化,而 allocUnsafe 创建的 Buffer 不会被初始化。 这意味着,尽管 allocUnsafe 比 alloc 要快得多,但是分配的内存片段可能包含可能敏感的旧数据。当 Buffer 内存被读取时,如果内存中存在较旧的数据,则可以被访问或泄漏。 这就是真正使 allocUnsafe 不安全的原因,在使用它时必须格外小心。
2、使用 buffer
包括以下七种使用场景。
const buf = Buffer.from('Hey!')
//1、Buffer(字节数组)可以像数组一样被访问
console.log(buf[0]) //72,返回值是Unicode码,用于标识 buffer 位置中的字符
//2、可以使用 toString() 方法打印 buffer 的全部内容
//如果使用数字(设置其大小)初始化 buffer,则可以访问到包含随机数据的已预初始化的内存(而不是空的 buffer)
console.log(buf.toString())
//3、获取 buffer 的长度:使用 length 属性
console.log(buf.length)
//4、迭代 buffer 的内容
for (const item of buf) {
console.log(item) //72 101 121 33 (Unicode码)
}
//5、更改 buffer 的内容:可以使用 write() 方法将整个数据字符串写入 buffer
buf.write('Hey!')
//也可以使用数组语法访问 buffer 一样,使用相同的方式设置 buffer 的内容
buf[1] = 111 //o
console.log(buf.toString()) //Hoy!
//6、复制 buffer:使用 copy() 方法可以复制 buffer
let bufcopy = Buffer.alloc(4) //分配 4 个字节
buf.copy(bufcopy)
//默认情况下,会复制整个 buffer。 另外的 3 个参数可以定义开始位置、结束位置、以及新的 buffer 长度
let bufcopy = Buffer.alloc(2) //分配 2 个字节。
buf.copy(bufcopy, 0, 0, 2)
bufcopy.toString() //'He'
//7、切片 buffer:使用 slice() 方法创建它。 第一个参数是起始位置,可以指定第二个参数作为结束位置
buf.slice(0).toString() //Hey!
const slice = buf.slice(0, 2)
console.log(slice.toString()) //He
buf[1] = 111 //o
console.log(slice.toString()) //Ho
写在最后
官方中文文档很详细,个人觉得看文档是学习的最佳方式。大家一定要学会看文档呀,多看官方文档。最后由于篇幅限制就不一一赘述了,忘了或者需要用到时就可以查阅文档。