前端 | Node.js新手入门常用模块
记录nodejs学习
Node.js是运行在服务端的Javascript,善于处理高并发,是前端程序员向小全栈方向发展的福音。对于前端程序员而言,掌握Node.js有助于自身技术的提升以及加深对web的理解。
本文总结Node.js入门级新手常用的模块以及这些模块的基本使用方法。😃
0x01 http
http模块是Node.js自带的模块之一,它可以实现与前端的通信,并且可以直接创建HTTP服务器,而无需在服务端安装Apache、Nginx等web服务器。
1.1 创建web服务器
1.1.1 方法一
如果你使用 VSCode 开发,并且安装了 Node Snippets
插件,可以输入 node-http-server
进行快捷创建。
注意,Node Snippets有很多同名插件,请认准 Chris Noring 开发的那一款。👍
按下 enter 键,就可以快捷添加以下代码👇:
var http = require('http');
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World');
}).listen(8081);
console.log('Server running at http://127.0.0.1:8081/');
一般我们习惯模块引用时使用常量,故可将第一行的
var
改为const
。
1.1.2 方法二
如果需要手动创建HTTP服务器,可以按照以下步骤进行理解性记忆。
- 引入http模块。
const http = require('http');
- 创建http服务器。
http.createServer((req,res)=>{
res.writeHead(200,{'Content-Type': 'text/plain;charset="utf-8"'});
res.write('Hello world!');
res.end();
}).listen(3000);
注意⚠
http.createServer()
中需要传入一个方法。可以是上一例中的function
生命的方法,也可以使用箭头函数。✔- 传入的方法中需要定义两个参数,第一个参数用来接收请求信息,包括请求的URL,包含的查询参数等;第二个参数用来接收响应信息,包括响应头以及相应内容等。
- 使用
res.writeHead()
方法可以设置响应头。其中第一个参数接收一个数字,为状态码;第二个参数接收一个JSON对象,包含其他的响应头信息。- 使用
res.write()
方法可以写入响应内容,响应内容将被展示在发送请求的页面上。💬- 一定不能忘记使用
res.end()
,否则会出现浏览器页面假死的现象。🤦♂️
0x02 url
1.1 解析URL
使用 url.parse()
来解析URL。
例如,解析 shaunyoung.cn
这个URL👇:
同时,我们可以解析带查询参数的URL👇:
我们可以给 url.parse()
中传入第二个参数,将解析得到的query转化成JSON格式👇:
1.2 将URL对象转化为字符串
使用 url.format()
方法可以将URL对象转化为字符串,是 url.parse()
的逆操作。🔧
1.3 添加或替换地址
使用 url.resolve()
可以添加或替换URL。
- 当第一个地址以
http://
或https://
开头时,使用url.resolve()
将添加地址。 - 否则将替换地址。🔗
0x03 fs
fs 模块是一个处理文件的模块,在处理浏览器发送的访问页面或文件的请求时用处很大。
fs模块包含了以下方法👨💻:
fs.stat()
——检测是文件还是目录fs.mkdir()
——创建目录fs.writeFile()
——创建写入文件fs.appendFile()
——追加写入文件fs.readFile()
——读取文件fs.readdir()
——读取目录fs.rename()
——重命名fs.rmdir()
——删除目录fs.unlink()
——删除文件fs.createReadStream()
——从文件流读取数据fs.createWriteStream()
——利用流写入文件- 管道流
3.1 检测是文件还是目录
使用 fs.stat()
方法可以检测一个URL指向的是文件还是目录。
const fs = require('fs');
fs.stat('hello.js', (error, stats) => {
if (error) {
console.log(error);
} else {
console.log(stats);
console.log(`文件:${stats.isFile()}`);
console.log(`目录:${stats.isDirectory()}`);
}
});
fs.stat()
需要传入两个参数,第一是文件的路径,第二是一个回调函数。回调函数需要接收报错信息 error
以及文件类型信息 stats
。
类型 | stats.isFile() | stats.ifDirectory() |
---|---|---|
文件 | true | false |
目录 | false | true |
3.2 创建目录
使用 fs.mkdir()
方法可以创建目录。
const fs = require('fs');
fs.mkdir('logs', (error) => {
if(error){
console.log(error);
} else {
console.log('成功创建目录:logs');
}
});
fs.mkdir()
方法需要传入两个参数,第一个是目录的路径,第二个是回调函数。回调函数需要接收报错信息 error
用来判断目录创建是否成功。
3.3 创建写入文件
使用 fs.writeFile()
方法可以创建一个文件并写入指定信息。
fs.writeFile('logs/hello.log', '您好 ~ \n', (error) => {
if(error) {
console.log(error);
} else {
console.log('成功写入文件');
}
});
fs.writeFile()
需要传入三个参数,第一个是创建的文件路径以及文件名,第二个是需要写入的内容(字符串形式),第三个是一个回调函数。回调函数需要接收一个报错信息 error
用来判断文件的创建与写入是否成功。
这个方法无法创建目录,故只能在已有目录中创建写入文件
注意:如果文件已经存在,则会覆盖原文件。如需在文件后追加内容请见下一点。
3.4 追加文件
使用 fs.appendFile()
方法可以给一个文件的末尾追加内容。
fs.appendFile('logs/hello.log', 'hello ~ \n', (error) => {
if(error) {
console.log(error);
} else {
console.log('成功写入文件');
}
});
fs.writeFile()
同样需要传入三个参数,在回调函数中需要传入报错信息。
注意:如果当前文件不存在,则该方法会自动创建一个文件,并且写入。
与
fs.writeFile()
方法相同,这个方法无法创建目录,只能在已有的目录中追加文件。
3.5 读取文件
使用 fs.readFile()
方法可以读取文件。
const fs = require('fs');
fs.readFile('logs/hello.log', 'utf8', (error, data) =>{
if (error) {
console.log(error);
} else {
console.log(data);
}
});
fs.readFile()
方法需要传入最少两个参数,中间的编码方式为可选参数,因为默认是 utf-8 编码,故不填也可以。第一个参数接收读取文件的路径,最后一个参数接收一个回调函数。回调函数中接收两个参数,一个是报错信息 error
,另一个是读取到的文件数据 data
。
3.6 读取目录
使用 fs.readdir()
方法读取目录。
const fs = require('fs');
fs.readdir('logs', (error, files) => {
if (error) {
console.log(error);
} else {
console.log(files);
}
});
fs.readdir()
方法需要两个参数,第一个是目录的路径,第二个是回调函数。回调函数中接收报错信息 error
以及该目录下文件列表 files
。其中 files
是一个 数组。
3.7 重命名或移动
使用 fs.rename()
方法对文件进行重命名或移动。
const fs = require('fs');
fs.rename('js/hello.log', 'js/greeting.log', (error) =>{
if (error) {
console.log(error);
} else {
console.log('重命名成功');
}
});
fs.rename()
方法需要传入三个参数,第一个是当前的路径及名称,第二个是新的路径及名称,第三个是回调函数。回调函数中接收 error
,用来判断重命名或移动是否成功。
这个方法可以重命名文件,可以移动文件,也可以边重命名边移动文件。
3.8 删除目录
使用 fs.rmdir()
方法删除目录。
const fs = require('fs');
fs.rmdir('logs', (error) =>{
if (error) {
console.log(error);
} else {
console.log('成功的删除了目录:logs');
}
});
fs.rmdir()
方法需要传入两个参数,第一个是需要删除的目录的路径,第二个是回调函数。回调函数接收一个 error
,用来判断删除是否成功。
注意:这个方法不支持删除非空文件夹,会报错
Error: ENOTEMPTY: directory not empty...
。
3.9 删除文件
使用 fs.unlink()
方法可以删除文件。
const fs = require('fs');
fs.unlink(`logs/${file}`, (error) => {
if (error) {
console.log(error);
} else {
console.log(`成功的删除了文件: ${file}`);
}
});
这个方法需要传入两个参数,第一个参数是需要删除的文件的路径,第二个参数是回调函数。
3.10 从文件流中读取数据
使用 fs.createReadStream()
来创建文件流,从文件流中读取数据。
const fs = require('fs');
var fileReadStream = fs.createReadStream('data.json'); //创建文件流
let count=0;
var str='';
fileReadStream.on('data', (chunk) => { //逐条循环读取数据
console.log(`${ ++count } 接收到:${chunk.length}`);
str+=chunk;
});
fileReadStream.on('end', () => { //监听读取数据结束
console.log('--- 结束 ---');
console.log(count);
console.log(str);
});
fileReadStream.on('error', (error) => { //监听报错信息
console.log(error);
});
3.11 写入文件
使用 fs.createWriteStream()
方法来利用流写入文件。
var fs = require("fs");
var data = '我是从数据库获取的数据,我要保存起来';
//创建一个可以写入的流,写入到文件output.txt中
var writerStream = fs.createWriteStream('output.txt');
//使用utf8编码写入数据
writerStream.write(data, 'UTF8');
//标记文件末尾
writerStream.end();
//处理流事件 --> finish事件
writerStream.on('finish', function () { /*finish - 所有数据已被写入到底层系统时触发。*/
console.log("写入完成。");
});
writerStream.on('error', function (err) {
console.log(err.stack);
});
console.log("程序执行完毕");
3.12 管道流
管道提供了一个输出流到输入流的机制。通常我们用于从一个流中获取数据并将数据传
递到另外一个流中。
我们把文件比作装水的桶,而水就是文件里的内容,我们用一根管子(pipe)连接两个桶使得水从一个
桶流入另一个桶,这样就慢慢的实现了大文件的复制过程。
var fs = require("fs");
//创建一个可读流
var readerStream = fs.createReadStream('input.txt');
//创建一个可写流
var writerStream = fs.createWriteStream('output.txt');
//管道读写操作
//读取input.txt文件内容,并将内容写入到output.txt文件中
readerStream.pipe(writerStream);
console.log("程序执行完毕");
0x04 path
4.1 获取后缀名
使用 path.extname()
方法可以获取到所访问文件的后缀名。在处理静态网页请求时非常实用。
const path = require('path');
path.extname('index.html');
// Returns: '.html'
path.extname('index.coffee.md');
// Returns: '.md'
path.extname('index.');
// Returns: '.'
path.extname('index');
// Returns: ''
path.extname('.index');
// Returns: ''
path.extname('.index.md');
// Returns: '.md'
获取到文件的后缀名后,就可以针对不同的后缀名来设置不同的响应头。
4.2 解析URL
使用 path.parse()
方法可以解析URL,获取到根目录、文件目录、文件名、后缀名等多项信息。
const path = require('path');
path.parse('/home/user/dir/file.txt');
// Returns:
// { root: '/',
// dir: '/home/user/dir',
// base: 'file.txt',
// ext: '.txt',
// name: 'file' }
0x05 ejs
ejs相当于一个HTML模板,它的结构和使用有点类似于php以及Vue等这些前端框架——通过传值、绑定、展示的方式,使用node.js+MongoDB+ejs理论上即可搭建一个动态网站。(官网传送门)
常用标签🏷:
<% %>
——控制流,可用于控制循环等<%= %>
——转义输出,可用于展示数据库查询到的数据