参考:https://www.jmjc.tech/less/114

  • 简介:

NodeJs,一个文件就是一个模块。

Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。

Node.js 诞生于 2009年,是一个基于 JavaScript 语言和 Google V8 引擎 开源的 Web 服务器项目,它让 JavaScript 第一次脱离了浏览器独立存在。

Node.js 被发明是用于解决服务器的 性能 问题,弥补 C++ 这一方面的一些繁琐。借助 JavaScript 天生异步事件驱动的特性和 V8 高性能引擎,加上市场已经有无数的 JS 语言使用者,所有在推出市场不久就非常的火爆。

发展到今天,Node 的性能依然是不错的,但可能已经不是它的主要卖点。PHP、Java 这些老牌的 Web 语言都在进步,后起之秀 Golang 也渐渐占领高性能服务器领域。所有它现在的卖点是 全栈,没错,学会了 Node.js 我们的前后端能统一使用一种语言开发,一个小的项目,用这种模式开发效率是非常高的,而且通用的语法让它的性价比变得非常的高,实在让人很难拒绝。

  • NPM

在开始写代码之前,我们还需要了解另外一个工具 npm,它是 Node.js 的包管理器,类似 Python 的 pip,是一个帮助我们从网络中下载 Node模块 到本地环境的工具。

npm 并不需要独立安装,它在 node 安装的时候已经附带。

$ npm -v
6.14.8
  • 初始化

在使用 npm 安装模块之前,需要进行初始化,我们建立一个项目工程 test,进入项目目录,然后运行 npm init 填写配置信息。如果成功, test 目录会多出一个 package.json 文件,它是 项目的配置文件,由 npm 管理控制。

  • 安装模块

我们运行这条命令 npm install jquery,尝试安装一个模块。之后会多出一个 node_modules,存放了我们刚刚安装的 jquery

  • 指令

npm 的更多用法。

// 安装
npm install module // 安装模块到当前工程目录
npm install module -g // 全局安装// 查找
npm ls module // 查找当前工程目录是否安装某模块
npm ls module -g // 全局查找// 卸载
npm uninstall module// 更新
npm update module
  • cnpm

由于国内的网络问题,使用 npm 下载模块有时会非常的慢。cnpm 是淘宝提供的一个 npm 镜像,用法和 npm 一样。

npm install -g cnpm // 安装
cnpm i ...
  • .npmrc

另一种种提升下载速度的办法,可以设置代理,通过 ~/.npmrc 文件。

registry=https://registry.npm.taobao.org/
disturl=https://npm.taobao.org/dist
  • 引用模块:

  • 例子:

Node会依次在内置模块、全局模块和当前模块下查找 。没写 "./" 目录可能会出错

录如下:

$ tree
.
|-- src
|   |-- MyEntry.js
|   `-- people
|       |-- family
|       |   `-- family.js
|       |-- man
|       |   `-- son.js
|       `-- woman
|           `-- daughter.js
`-- tsconfig.json5 directories, 5 files

son.js

module.exports = {showInfo:function(name,age){console.log("son::showInfo: ",name,", ",age);},showName:function(name){console.log("son::showName ",name);}
}

daughter.js

module.exports = {showInfo:function(name,age){console.log("daughter::showInfo",name,", ",age);}
};

family.js

var son = require("../man/son");
var daughter = require("../woman/daughter");
module.exports = {son: son,showInfo: function () {son.showInfo("jim", 9);daughter.showInfo("marry", 13);}
};

MyEntry.js

var family = require("./people/family/family");family.showInfo();
family.son.showInfo("jj", 33);

显示结果:

$ node src/MyEntry.js
son::showInfo:  jim ,  9
daughter::showInfo marry ,  13
son::showInfo:  jj ,  33
  • HTTP 模块

我们知道,Node.js 的应用场景是 高性能服务器,而这一切的工作都是基于 HTTP,所以 HTTP模块 也是 Node.js 的核心。

HTTP 模块的作用,就是让我们可以构建一个 HTTP 服务器,通过简单的几行代码,就能完成。

var http = require("http");
var server = http.createServer(function(request,response){response.writeHead(200,{"Content-Type":"text/html"});response.end("<h1>hello world</h1>");
});server.listen(8877);
console.log("server is running at http://127.0.0.1:8877/");

运行之后,访问 localhost:8877 就得到响应内容 hello world

  • 应用扩展

服务器的应用,其实就是对请求和响应的处理 (request & response) ,通过不同的客户端请求,返回不同的响应状态。

var http = require("http");
var server = http.createServer(function (request, response) {/*request 响应对象response 请求对象*/if (request.method === 'GET' && request.url === '/gg.html') { // 响应首页response.writeHead(200, { 'Content-Type': 'text/html' })response.end('<h1>Hello worldxx!</h1>')}else { // 其他页面不存在response.writeHead(404)response.end('404 Not Found')}
})server.listen(8877)console.log('server is running at http://127.0.0.1:8877/');

浏览器访问http://127.0.0.1:8877/gg.html,显示结果:Hello worldxx!

  • node.js文件操作  fs模块

  • global

global 是 Node.js 的 全局对象,相当于 JavaScript 中的 window

// global 包含了当前环境的很多信息
consoel.log(global) // 当前文件名称
global.__filename// 当前目录名称
global.__dirname...
  • path

路径处理模块。

var path = require('path')// 格式化
path.normalize('c:/user') // c:\user | 针对 window 操作系统文件路径// 路径解析
path.parse('/Users/jason/Desktop/test/node')
/*
{ root: '/',dir: '/Users/jason/Desktop/test',base: 'node',ext: '',name: 'node' }
*/// 路径拼接
console.log(path.join('/Users', '/jason/Desktop/node')) // /Users/jason/Desktop/node
  • url

网址处理模块。

const log = console.log;
// var url = require("url")
var np = new URL('https://mp.csdn.net:8080/editor/html/114321403/')
log("np = ",np);/*
np =  URL {href: 'https://mp.csdn.net:8080/editor/html/114321403/',origin: 'https://mp.csdn.net:8080',protocol: 'https:',username: '',password: '',host: 'mp.csdn.net:8080',hostname: 'mp.csdn.net',port: '8080',pathname: '/editor/html/114321403/',search: '',searchParams: URLSearchParams {},hash: ''}
*/  
  • fs

文件处理模块,Node.js 天生是 异步 执行的,但 fs模块 也支持了 同步 的功能。

异步写入

var fs = require('fs')// 写入内容 “writed” 到当前目录的 "filename" 文件,如果该文件不错误,自动创建后写入
fs.writeFile('./filename.txt', 'writed', function (err) {if (err) {console.log(err) // 写入失败信息} else {console.log('ok') // 写入成功提示}
})

异步读取

var fs = require('fs')// 读取当前目录的 filename 文件
fs.readFile('./filename.txt', 'utf-8', function (err, data) { // 默认utf-8if (err) {console.log(err) // 读取失败打印错误代码} else {console.log(data) // 读取成功输出}
})

同步写入、追加写入、同步读取

const log = console.log;
var fs = require('fs')//同步写入
try {fs.writeFileSync("./filename.txt", "you sync")
} catch (err) {log(err);
}//追加写入
try {fs.appendFileSync("./filename.txt", "\r\n" + "app new");
} catch (err) {log("err appendSync ", err)
}//同步读取
try {var data = fs.readFileSync("./filename.txt", "utf-8");console.log("data = ", data);//you sync
} catch (err) {log("err read ", err)
}

异步读取目录

var fs = require('fs')// 列出指定目录下的 “目录文件”
fs.readdir('./', function (err, file) {if (err) {console.log(err) } else {console.log("files = ",file) }
})/**files =  ['.vscode','filename.txt','node_modules','package-lock.json','package.json','src'
]*/

文件信息

异步获取

const log = console.log;
var fs = require('fs')fs.stat('filename.txt', function (err, stat) {if (err) {console.log(err)} else {log(stat.isFile()) // 是否是文件log(stat.isDirectory()) // 是否是目录     log(stat.size) // 文件大小:     log(stat.birthtime) // 创建时间 Date对象     log(stat.mtime) // 修改时间 Date对象}
})

同步获取

const log = console.log;
var fs = require('fs')try {var stat = fs.statSync('filename.txt');log(stat.isFile()) // 是否是文件log(stat.isDirectory()) // 是否是目录     log(stat.size) // 文件大小:     log(stat.birthtime) // 创建时间 Date对象     log(stat.mtime) // 修改时间 Date对象} catch (e) {log("e = ", e);
}/**
$ node src/entry.js
true
false
17
2021-03-04T14:17:18.978Z
2021-03-04T14:27:57.593Z*/
  • Node.js Buffer 缓冲区

Buffer 除了转码的作用外,它更多时候还用作缓冲区,用于数据的缓存。

Buffer.from(), Buffer.alloc() 都是创建一个buffer, Buffer.from()从字符串或者数组创建一个buffer, Buffer.alloc()是创建一个指定大小的buffer。

1.创建Buffer的两种方法:var  buf = Buffer.alloc();    //返回一个指定大小的被填满的Buffer实例;var buf = Buffer.from()      //返回一个新建的包含所提供的字节数组的副本的Buffer;

例子:

const log = console.log;
var aSentence = "i am a sentence"
log("aSentence = ",aSentence, ", len = ",aSentence.length);
const buf1 = Buffer.from(aSentence)
log("buf1 old = ", buf1, ", len = ", Buffer.byteLength(buf1), ", buf1.tostring = ", buf1.toString());
buf1.write("你好");
log("buf1 new = ", buf1, ", len = ", Buffer.byteLength(buf1), "buf1.tostring = ", buf1.toString());const buf2 = Buffer.alloc(50);
buf2.write("you are right");
log("buf2 = ", buf2, ", len = ", Buffer.byteLength(buf2), ", buf2.toString = ", buf2.toString());/*
aSentence =  i am a sentence , len =  15
buf1 old =  <Buffer 69 20 61 6d 20 61 20 73 65 6e 74 65 6e 63 65> , len =  15 , buf1.tostring =  i am a sentence
buf1 new =  <Buffer e4 bd a0 e5 a5 bd 20 73 65 6e 74 65 6e 63 65> , len =  15 buf1.tostring =  你好 sentence
buf2 =  <Buffer 79 6f 75 20 61 72 65 20 72 69 67 68 74 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00> , len =  50 , buf2.toString =  you are right
*/
  • Node.js Stream 流

  • Stream

 是一种抽象的概念,它表示的含义是,文件的传输,就像水流一样,通过 管道 一点一点的传向目的地。流的背后,是一个又一个的 缓冲区,提前为数据做好了准备。

我们在前面小节列举过 fs模块,用它读取过文件。它的做法是把数据一次性读取到内存中,如果写入是一次性把内存中的数据写入到磁盘。如果我们读取的文件非常小,那这样做是没有问题,但是如果是大容量的文件 10G,甚至更大,那么这种模型就很有问题了。

而 Stream 的理念是 边读边取,用这种 IO 方式就破解了上面的难题,节省空间和时间。

/*以流的形式读取文件
*/
var fs = require('fs');
var rs = fs.createReadStream('filename', 'utf-8') // 得到的 rs 是一个输出流句柄,通过事件触发得到它到状态// 数据开始读取...
// data 事件可能会读取多次,每次读取一块数据
rs.on('data', function (chunk) {console.log('DATA:')console.log(chunk)
})// 读完触发
rs.on('end', function () {console.log('END')
})// 错误触发
rs.on('error', function (err) {console.log('ERROR: ' + err)
})/* 以流的形式写入文件
*/
var fs = require('fs')
var ws = fs.createWriteStream('filename', 'utf-8')
ws.write('1') // 一点
ws.write('2') // 一点
ws.end() // 写入

pipe

管道是 Unix 的核心思想之一,如果你接触过 Linux 操作系统,那么对下面这个操作就很容易理解。

var fs = require('fs')
var rs = fs.createReadStream('a.txt') // 输出流
var ws = fs.createWriteStream('b.txt') // 输入流
rs.pipe(ws) // 输出通过管道流向输入/* 上面做的工作,是读取 a.txt 的内容,写入到 b.txt在 Linux 中它有一个名字,叫做 “重定向”
*/
  • Node.js Crypto 模块

  • 摘要算法

    crypto模块 是 Node.js 内置的密码模块,封装了一些密码处理方法。 crypto 摘要算法的使用方法,几乎跟 Python 的 hashlib模块 是一样的,参考 - 摘要算法。

查看是否安装了crypto模块

PS E:\study\js\two> npm list crypto -g
C:\Users\andrew\AppData\Roaming\npm
`-- crypto@1.0.1

没安装的话就执行安装命令:

npm  install  crypto  -g
const crypto = require('crypto')hash = crypto.createHash('md5') // md5
hash.update('date')
console.log(hash.digest('hex')) // 5fc732311905cb27e82d67f4f6511f7f// 增强
hash = crypto.createHash('sha1') // sha1
hash.update('date')
console.log(hash.digest('hex')) // e927d0677c77241b707442314346326278051dd6// 越强越安全,执行效率越低
// sha256
// sha512
// ...
  • hmac 算法
/* hmac 算法,增强版的摘要算法,需要密钥密钥,通常的也叫做 “盐”
*/hmacsha256 = crypto.createHmac('sha256', 'secret-key')
hmacsha256.update('data')
hmacsha256.update('append data')
hmacsha256.digest('hex'))// 对应还有 hmacmd5 128、hmacsha1 160 ... 

对称加密

对称加密是一种双向加密算法,跟摘要算法的单向加密不同,它是支持加解密的,通过配备一个 密钥 完成。AES 是对称加密的一种,常见算法有 aes192aes-128-ecbaes-256-cbc

const crypto = require('crypto')// 加密
function aesEncrypt(data, key) {let cipher = crypto.createCipher('aes192', key)let crypted = cipher.update(data, 'utf8', 'hex')return cipher.final('hex')
}// 解码
function aesDecrypt(encrypt, key) {let decipher = crypto.createDecipher('aes192', key);let decrypted = decipher.update(encrypt, 'hex', 'utf8');return decipher.final('utf8');
}let encrypt = aesEncrypt('data','key') // 加密
console.log(encrypt) // 998118c1207f9e6fa5ee610c5bfd8ef0let data = aesDecrypt(encrypt, 'key') // 解密
console.log(data) // data
  • Node.js Mysql

  • Mysql

mysql 是一个第三方的数据库模块,使用前需要安装 npm i mysql

const mysql = require('mysql')// 连接 mysql 服务器
const connection = mysql.createConnection({host: '127.0.0.1',port: '3306',user: 'root',password: ''
})// 执行SQL
connection.query(sql, function (err, result) {err // 错误信息result // 结果
})// 销毁连接 | 由于 JS 是异步的,所以当前代码会在执行 SQL 之前就销毁了连接
connection.destroy()
  • Pool 连接池

用 createConnection 创建 Mysql 连接,每执行一次 connection.query 都是一个全新的连接,会造成一个资源的极大浪费,降低性能。

连接池是另外的一种执行方法,它一次性的创建了多个连接,然后根据客户端的查询,自动的 分发复用管理 这些连接。

const mysql = require('mysql')// 链接池:创建多个链接、复用与分发链接
const pool = mysql.createPool({host: '127.0.0.1',port: '3306',user: 'root',password: ''
})// 封装
query = function(sql,callback){  pool.getConnection(function(err,connection){  connection.query(sql,function(err,results){  callback(err, results) // 结果回调connection.release() // 释放连接资源 | 跟 connection.destroy() 不同,它是销毁})}  })
}// 随机分配一个连接
pool.query(sql, function (err, result) {// ...
}

SQL 注入

在写 SQL 语句的时间尽量不要使用 SQL 拼装,因为很容易被 SQL注入,从而引发安全问题,如果数据和 SQL 语句需要分离,那么请使用 占位符 的方式。

connection.query("select * from users where id = ? and name = ?", [1, 'jmjc'], (err, result)=>{}) // 这种方式 mysql 模块内部会调用 escape 方法,过滤掉一些非法的操作/*当前我们也可以自己使用 escape 方法
*/
connection.query('select * from users where id = ' + connection.escape(userId), (err, result) => {})/*或者 format 方法
*/
const sql = "select * from ?? where ?? = ?"
const inserts = ['users', 'id', 1]
sql = mysql.format(sql, inserts) // select * from users where id = 1
  • Node.js Request 模块

  • Request

request 是一个流行 Node.js 第三方 HTTP 请求工具。虽然目前市场上很多的 网络爬虫 应用,都是基于 Python,但事实上 Node.js 也写非常适合这个领域。request 这个模块,就能帮助我们构建不错的爬虫应用。

运行 npm i request 安装它。

  • GET 请求
const request = require('request')request('https://www.baidu.com/', function (err, response, body) {/*response 响应信息的集合*/if (!err && response.statusCode == 200) { console.log(body)}
})
  • POST 请求
/*application/x-www-form-urlencoded (普通表单)
*/
request.post({url:url, form:{key:'value'}}, function (error ,response, body) {// 返回的结果和 GET 一样
})/*application/json (JSON表单)
*/
request({url: url,method: "POST",json: true,headers: {"content-type": "application/json",},body: JSON.stringify({key: 'value'})
}, function(error, response, body) {// ...
})/*multipart/form-data (上传文件)
*/
var url = 'http://192.168.0.102:3000/home'
var formData = {// 普通文本field: 'value',// 文件file: fs.createReadStream('./img.jpg'),
}request.post({url:url, formData: formData}, function (error, response, body) {  // ...
})
  • 保存文件

一个 request 结合 pipe 重定向文件流的实例。

request('https://www.jmjc.tech/public/home/img/flower.png').pipe(fs.createWriteStream('./flower.png')) // 下载文件到本地
  • Node.js WebSocket 协议

  • WebSocket

websocket 是 HTML5 标准的一个新的 网络协议。它是基于 HTTP 协议之上的扩展,是一种可以双向通信的协议。

传统的 HTTP 协议 通信,服务端是不能主动发信息给客户端的。它必须是客户端一个请求,服务器一个响应,一来一回。那么基于这种通信的方式,如果想构建一个网络在线聊天应用,就没有办法,因为不能主动推送信息,要客户端一直刷新。

websocket 可以跟 HTTP 协议共用一个端口,它协议的前缀是 ws://,如果是 HTTPS,那么就是 wss://,webSocket 没有同源限制,客户端可以发送任意请求到服务端,只要目标服务器允许。

  • WS 模块

ws 是一个第三方的 websocket 通信模块,需要安装 npm i ws,websocket 的通信模型跟 HTTP 是一样的,服务端对应客户端模型。

nodejs导入模块相关推荐

  1. Nodejs的模块系统以及require的机制

    一.简介 Nodejs 有一个简单的模块加载系统.在 Nodejs 中,文件和模块是一一对应的(每个文件被视为一个独立的模块),这个文件可能是 JavaScript 代码,JSON 或编译过的C/C+ ...

  2. 关于python导入模块和package的一些深度思考

    背景 在python中有导入模块和导入package一说,这篇文章主要介绍导入模块和package的一些思考. 首先什么是模块?什么是package? 模块:用来从逻辑上组织python代码(变量,函 ...

  3. Python Day26:多态、封装、内置函数:__str__、__del__、反射(反省)、动态导入模块...

    ## 多态 ```python OOP中标准解释:多个不同类型对象,可以响应同一个方法,并产生不同结果,即为多态 多态好处:只要知道基类使用方法即可,不需要关心具体哪一个类的对象实现的,以不变应万变, ...

  4. 深入探讨Python的import机制:实现远程导入模块 | CSDN博文精选

    来源 | Python编程时光(ID:Python-Time) 所谓的模块导入,是指在一个模块中使用另一个模块的代码的操作,它有利于代码的复用. 也许你看到这个标题,会说我怎么会发这么基础的文章? 与 ...

  5. 关于学习Python的一点学习总结(39->导入模块)

    79.1.导入模块: 先举个例子:>>> array=random.randint(1,10)Traceback (most recent call last):File " ...

  6. day8 动态导入模块、socket进阶

    文章目录 1. 动态导入模块 2. socket 进阶 1. 动态导入模块 文件目录如下: aa.py 文件中: class C(object):def __init__(self):self.nam ...

  7. python导入模块有同名_Python:导入与函数同名的模块

    背景:第一次在SE上提问.我在 Python方面还很陌生,而且在编程方面也不是很有经验.我已经四处寻找,但我没有找到这个问题的答案,我非常感谢你的帮助. 我的问题是:如何导入与函数同名的模块? 具体来 ...

  8. python中导入模块用什么命令_Python导入模块的技巧

    作为使用Python的开发者,我们一开始学习的内容之一就是如何导入Python的各种模块或库.但是我们注意到,那些经常使用Python的用户并不一定都知道Python的导入机制其实非常灵活.在本文中, ...

  9. python导入模块快捷键_Python中的模块导入和读取键盘输入的方法

    导入模块 import 语句 想使用Python源文件,只需在另一个源文件里执行import语句,语法如下: ? 当解释器遇到import语句,如果模块在当前的搜索路径就会被导入. 搜索路径是一个解释 ...

最新文章

  1. modelsim(1):经常使用的测试设计的结构
  2. html给span标签设置index,html – 绝对定位嵌套元素的z-index
  3. uniapp中使用微信jssdk
  4. Python--进程、线程、协程对比
  5. Oracle优化笔记
  6. Golang 【大字符串相加,求和】
  7. python 解除excel的密码_我帮公司财务写了个“群发工资条”的Python脚本!
  8. Python的安装以及编译器的安装
  9. SpringBoot项目在Gitee的控管步骤
  10. nodejs的简单爬虫
  11. 试试用word发博客
  12. 数控机床现场数据采集与边缘计算方案
  13. 太牛了,2万字用Python深度探索金庸小说世界!
  14. centos7安装tree命令
  15. mfc word转pdf
  16. 国内商务邮箱品牌——TOM企业邮箱
  17. 纯干货:微软漏洞中国第一人黄正——如何用正确姿势挖掘浏览器漏洞(附完整 PPT)
  18. matlab(slove)如何应用,README.md/matlab/slove at master · SeanXP/README.md · GitHub
  19. 友邦人寿发布非一线差异化发展策略,稳步加速中国市场拓展布局
  20. bcoma 应用程序发生错误_打开网页老是出现《应用程序错误》是怎么回事?

热门文章

  1. 好品质选得力:得力品牌给力在哪里
  2. 一直没看的无人机定高
  3. 苹果电脑电池的维护和保养(适用Macbook和Macbook Pro)
  4. matlab dct反变换,MATLAB中 DCT变换、DCT反变换、分块DCT变换
  5. Ubuntu/Linux 安装Android-sdk 和 commandlinetools
  6. 打哈欠 为什么会传染
  7. 百度2016校园招聘-开发测试工程师-在线编程题1-商队运输费
  8. SQL Server 使用作业设置定时任务之一
  9. 02.青龙面板——薅京东羊毛,自动获取京豆、自动浇水、做任务
  10. LoadRunner的简单使用《第一篇》