Node.js 基本内置模块及其作用(8个)-fs (File System)模块、path模块、http模块、events模块、os模块、url模块、crypto模块、querystring模块

Node.js 基本内置模块

Node.js 提供了许多内置模块,这些模块可以帮助开发者快速实现各种功能。
注意:想用到这些内置模块里的功能是需要先用const 变量名 = require(‘模块名’); 引入模块

1.fs (File System)模块

作用:用于处理文件系统操作,如读取、写入、删除文件或读取、写入、删除文件夹等

(1)读取文件内容

fs.readFile('example.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});
//err参数表示报错参数
//data参数表示读取这个文件里面的数据

(2)写入文件

//异步写入
fs.writeFile('example.txt', 'Hello World!', (err) => {
  if (err) throw err;
  console.log('File has been written!');
});
//err参数表示报错参数
//同步写入
try{
    fs.writeFileSync('./fileForWrite1.txt', 'hello world', 'utf8');
    console.log('文件写入成功');
}catch(err){
    throw err;
}

(3)删除文件

//异步
fs.unlink('example.txt', (err) => {
  if (err) throw err;
  console.log('File has been deleted!');
});
//err参数表示报错参数
//同步
fs.unlinkSync('./fileForUnlink.txt');

(4)创建目录

//异步版本(如果目录已存在,会报错)
var fs = require('fs');
fs.mkdir('./hello', function(err){
    if(err) throw err;
    console.log('目录创建成功');
});
//同步版本
fs.mkdirSync('./hello');

(5)文件重命名

//异步
// fs.rename(oldPath, newPath, callback)
var fs = require('fs');

fs.rename('./hello', './world', function(err){
    if(err) throw err;
    console.log('重命名成功');
});
//同步
var fs = require('fs');
fs.renameSync('./world', './hello');

2.path模块

作用:用于处理文件和目录路径。
在nodejs中,path是个使用频率很高,但却让人又爱又恨的模块。部分因为文档说的不够清晰,部分因为接口的平台差异性。

(1)获取所在路径

var path = require('path');
var filepath = '/tmp/demo/js/test.js';

// 输出:/tmp/demo/js
console.log( path.dirname(filepath) );

(2)获取文件名

严格意义上来说,path.basename(filepath) 只是输出路径的最后一部分,并不会判断是否文件名。
但大部分时候,我们可以用它来作为简易的“获取文件名“的方法。

var path = require('path');

// 输出:test.js
console.log( path.basename('/tmp/demo/js/test.js') );

// 输出:test
console.log( path.basename('/tmp/demo/js/test/') );

// 输出:test
console.log( path.basename('/tmp/demo/js/test') );

(3)获取文件扩展名

var path = require('path');
var filepath = '/tmp/demo/js/test.js';
// 输出:.js
console.log( path.extname(filepath) );
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 ''

3.http模块----内容较多后续会专门讲解

作用:用于创建 HTTP 服务器和客户端。

大多数nodejs开发者都是冲着开发web server的目的选择了nodejs。正如官网所展示的,借助http模块,可以几行代码就搞定一个超迷你的web server。
在nodejs中,http可以说是最核心的模块,同时也是比较复杂的一个模块。上手很简单,但一旦深入学习,不少初学者就会觉得头疼,不知从何入手。
本文先从一个简单的例子出发,引出http模块最核心的四个实例。看完本文,应该就能够对http模块有个整体的认识。

在下面的例子中,我们创建了1个web服务器、1个http客户端:

服务器server:接收来自客户端的请求,并将客户端请求的地址返回给客户端。
客户端client:向服务器发起请求,并将服务器返回的内容打印到控制台。

var http = require('http');

// http server 例子
var server = http.createServer(function(serverReq, serverRes){
    var url = serverReq.url;
    serverRes.end( '您访问的地址是:' + url );
});

server.listen(3000);

// http client 例子
var client = http.get('http://127.0.0.1:3000', function(clientRes){
    clientRes.pipe(process.stdout);
});

代码解释:

在上面这个简单的例子里,涉及了4个实例。大部分时候,serverReq、serverRes 才是主角。

server:http.Server实例,用来提供服务,处理客户端的请求。
client:http.ClientReques实例,用来向服务端发起请求。
serverReq/clientRes:其实都是 http.IncomingMessage实。serverReq 用来获取客户端请求的相关信息,如request header;而clientRes用来获取服务端返回的相关信息,比如response header。
serverRes:http.ServerResponse实例

4.events模块

作用:用于处理事件驱动编程。
events模块是node的核心模块之一,几乎所有常用的node模块都继承了events模块,比如http、fs等

例子1:单个事件监听器

var EventEmitter = require('events');
//创建一个名为 Man 的新类,它扩展了 EventEmitter 类
class Man extends EventEmitter {}
// 创建 Man 类的新实例
var man = new Man();
man.on('wakeup', function(){
    console.log('man has woken up');
});
man.emit('wakeup');
// 输出如下:
// man has woken up

例子2:同个事件,多个事件监听器

var EventEmitter = require('events');
//创建一个名为 Man 的新类,它扩展了 EventEmitter 类
class Man extends EventEmitter {}
var man = new Man();
man.on('wakeup', function(){
    console.log('man has woken up');
});
man.on('wakeup', function(){
    console.log('man has woken up again');
});
man.emit('wakeup');
// 输出如下:
// man has woken up
// man has woken up again

例子3:只运行一次的事件监听器

var EventEmitter = require('events');
//创建一个名为 Man 的新类,它扩展了 EventEmitter 类
class Man extends EventEmitter {}
var man = new Man();
man.on('wakeup', function(){
    console.log('man has woken up');
});
man.once('wakeup', function(){
    console.log('man has woken up again');
});
man.emit('wakeup');
man.emit('wakeup');
// 输出如下:
// man has woken up
// man has woken up again
// man has woken up

例子4:注册事件监听器前,事件先触发

var EventEmitter = require('events');
//创建一个名为 Man 的新类,它扩展了 EventEmitter 类
class Man extends EventEmitter {}
var man = new Man();
man.emit('wakeup', 1);
man.on('wakeup', function(index){
    console.log('man has woken up ->' + index);
});
man.emit('wakeup', 2);
// 输出如下:
// man has woken up ->2

例子5:异步执行,还是顺序执行

var EventEmitter = require('events');
//创建一个名为 Man 的新类,它扩展了 EventEmitter 类
class Man extends EventEmitter {}
var man = new Man();
man.on('wakeup', function(){
    console.log('man has woken up'); // 代码1
});
man.emit('wakeup');
console.log('woman has woken up');  // 代码2
// 输出如下:
// man has woken up
// woman has woken up

例子6:移除事件监听器

var EventEmitter = require('events');
function wakeup(){
    console.log('man has woken up');
}
//创建一个名为 Man 的新类,它扩展了 EventEmitter 类
class Man extends EventEmitter {}
var man = new Man();
man.on('wakeup', wakeup);
man.emit('wakeup');
man.removeListener('wakeup', wakeup);
man.emit('wakeup');
// 输出如下:
// man has woken up

5.os模块—不经常使用

作用:用于获取操作系统相关信息。

const os = require('os');

// 获取操作系统平台
console.log(os.platform()); // 输出: darwin(MacOS)、win32(Windows)或linux(Linux)

// 获取总内存量(以字节为单位)
console.log(os.totalmem()); // 输出: 17179869184(示例值)

6.url模块

作用:用于解析和格式化 URL
nodejs中,提供了url这个非常实用的模块,用来做URL的解析。在做node服务端的开发时会经常用到。使用很简单,总共只有3个方法

url模块三个方法分别是:

1.parse(urlString):将url字符串,解析成object,便于开发者进行操作。
2.format(urlObj):.parse() 方法的反向操作。
3.resove(from, to):以from作为起始地址,解析出完整的目标地址(还是看直接看例子好些

(1)url解析:url.parse()

完整语法:url.parse(urlString[, parseQueryString[, slashesDenoteHost]])

var url = require('url');
var str = 'http://Chyingp:HelloWorld@ke.qq.com:8080/index.html?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1#part=1';
var obj = url.parse(str);
console.log(obj);

输出如下:

Url {
  protocol: 'http:',
  slashes: true,
  auth: 'Chyingp:HelloWorld',
  host: 'ke.qq.com:8080',
  port: '8080',
  hostname: 'ke.qq.com',
  hash: '#part=1',
  search: '?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1',
  query: 'nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1',
  pathname: '/index.html',
  path: '/index.html?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1',
  href: 'http://Chyingp:HelloWorld@ke.qq.com:8080/index.html?nick=%E7%A8%8B%E5%BA%8F%E7%8C%BF%E5%B0%8F%E5%8D%A1#part=1' }

对输出解释:
protocol:协议,需要注意的是包含了:,并且是小写的。
slashes:如果:后面跟了两个//,那么为true。
auth:认证信息,如果有密码,为usrname:passwd,如果没有,则为usrname。注意,这里区分大小写。
host:主机名。注意包含了端口,比如ke.qq.com:8080,并且是小写的。
hostname:主机名,不包含端口,并且是小写的。
hash:哈希部分,注意包含了#。
search:查询字符串,注意,包含了?,此外,值是没有经过decode的。
query:字符串 或者 对象。如果是字符串,则是search去掉?,其余一样;如果是对象,那么是decode过的。
path:路径部分,包含search部分。
pathname:路径部分,不包含search部分。
href:原始的地址。不过需要注意的是,protocol、host会被转成小写字母

(2)url拼接:url.format(urlObject)

url.parse(str)的反向操作,没什么好说的。urlObject包含了很多字段,比如protocol、slashes、protocol等,且不一定需要全部传,所以有一套解析逻辑。
过程比较冗长,大部分时候不需要用到

(3)url.resolve(from, to)
url.resolve('/one/two/three', 'four')         // '/one/two/four'
url.resolve('http://example.com/', '/one')    // 'http://example.com/one'
url.resolve('http://example.com/one', '/two') // 'http://example.com/two'

7.crypto模块----知识较难

(1)hash例子

hash.digest([encoding]):计算摘要。encoding可以是hex、latin1或者base64。如果声明了encoding,那么返回字符串。否则,返回Buffer实例。
注意:调用hash.digest()后,hash对象就作废了,再次调用就会出错。

hash.update(data[, input_encoding]):input_encoding可以是utf8、ascii或者latin1。如果data是字符串,且没有指定 input_encoding,则默认是utf8。
注意:hash.update()方法可以调用多次。

var crypto = require('crypto');
var fs = require('fs');

var content = fs.readFileSync('./test.txt', {encoding: 'utf8'});
var hash = crypto.createHash('sha256');
var output;

hash.update(content);

output = hash.digest('hex'); 

console.log(output);
// 输出内容为:
// b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9

(2)HMAC例子

HMAC的全称是Hash-based Message Authentication Code,也即在hash的加盐运算。

算法细节可以参考附录链接,具体到使用的话,跟hash模块差不多,选定hash算法,指定“盐”即可。

var crypto = require('crypto');
var fs = require('fs');

var secret = 'secret';
var hmac = crypto.createHmac('sha256', secret);
var input = fs.readFileSync('./test.txt', {encoding: 'utf8'});

hmac.update(input);

console.log( hmac.digest('hex') );
// 输出:
// 734cc62f32841568f45715aeb9f4d7891324e6d948e4c6c60c0621cdac48623a

(3)加密/解密

加解密主要用到下面两组方法:
加密:
crypto.createCipher(algorithm, password)
crypto.createCipheriv(algorithm, key, iv)
解密:
crypto.createDecipher(algorithm, password)
crypto.createDecipheriv(algorithm, key, iv)

crypto.createCipher(algorithm, password)

algorithm:加密算法,比如aes192,具体有哪些可选的算法,依赖于本地openssl的版本,可以通过openssl list-cipher-algorithms命令查看支持哪些算法。
password:用来生成密钥(key)、初始化向量(IV)。

var crypto = require('crypto');
var secret = 'secret';
var cipher = crypto.createCipher('aes192', secret);
var content = 'hello';
var cryptedContent;
cipher.update(content);
cryptedContent = cipher.final('hex');
console.log(cryptedContent);
// 输出:
// 71d30ec9bc926b5dbbd5150bf9d3e5fb
crypto.createCipheriv(algorithm, key, iv)

相对于 crypto.createCipher() 来说,crypto.createCipheriv() 需要提供key和iv,而 crypto.createCipher() 是根据用户提供的 password 算出来的。
key、iv 可以是Buffer,也可以是utf8编码的字符串,这里需要关注的是它们的长度:
key:根据选择的算法有关,比如 aes128、aes192、aes256,长度分别是128、192、256位(16、24、32字节)
iv:都是128位(16字节)

var crypto = require('crypto');
var key = crypto.randomBytes(192/8);
var iv = crypto.randomBytes(128/8);
var algorithm = 'aes192';
function encrypt(text){
    var cipher = crypto.createCipheriv(algorithm, key, iv);
    cipher.update(text);
    return cipher.final('hex');
}
function decrypt(encrypted){
    var decipher = crypto.createDecipheriv(algorithm, key, iv);
    decipher.update(encrypted, 'hex');
    return decipher.final('utf8');
}
var content = 'hello';
var crypted = encrypt('hello');
console.log( crypted );

var decrypted = decrypt( crypted );
console.log( decrypted );  // 输出:utf8

8.querystring模块

在nodejs中,提供了querystring这个模块,用来做url查询参数的解析,使用非常简单。
模块总共有四个方法,绝大部分时,我们只会用到 .parse().stringify() 两个方法。剩余的方法,感兴趣的同学可自行查看文档。
.parse():对url查询参数(字符串)进行解析,生成易于分析的json格式。
.stringif():跟**.parse()**相反,用于拼接查询查询。

(1)查询参数解析:querystring.parse()

参数:querystring.parse(str[, sep[, eq[, options]]])
第四个参数几乎不会用到,直接不讨论. 第二个, 第三个其实也很少用到,但某些时候还是可以用一下。直接看例子

var querystring = require('querystring');
var str = 'nick=casper&age=24';
var obj = querystring.parse(str);
console.log(JSON.stringify(obj, null, 4));

输出如下:

{
    "nick": "casper",
    "age": "24"
}

再来看下两个参数:sep、eq有什么作用。相当于可以替换&、=为自定义字符,对于下面的场景来说还是挺省事的。

var str1 = 'nick=casper&age=24&extra=name-chyingp|country-cn';
var obj1 = querystring.parse(str1);
var obj2 = querystring.parse(obj1.extra, '|', '-');
console.log(JSON.stringify(obj2, null, 4));

输出如下:

{
    "name": "chyingp",
    "country": "cn"
}

(2)查询参数拼接:querystring.stringify()

语法:querystring.stringify(obj[, sep[, eq[, options]]])
相当于parse的逆向操作。直接看代码

var querystring = require('querystring');

var obj1 = {
    "nick": "casper",
    "age": "24"
};
var str1 = querystring.stringify(obj1);
console.log(str1);

var obj2 = {
    "name": "chyingp",
    "country": "cn"
};
var str2 = querystring.stringify(obj2, '|', '-');
console.log(str2);

输出如下:

nick=casper&age=24
name-chyingp|country-cn
  • 25
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值