nodejs和vue的那个事

By admin in 4858美高梅 on 2019年4月14日
  1. nodejs

Node.js 是叁个根据 Chrome
V捌 引擎的 JavaScript
运营条件。 

Node.js是当前卓殊炎热的技能,不过它的降生经历却很奇妙。

cmd命令:

   ./  当前目录

   ../ 上一级

   dir  查看当前目录

   ls  查看当前目录下文件

   windows 切换盘符 d:

   cls清屏

   cd +文件加名

>一.意在提供一种简易的塑造可伸缩网络程序的主意

 

明明,在Netscape设计出JavaScript后的短距离赛跑多少个月,JavaScript事实季春经是前端开发的唯一标准。

es6:

1.let/const

二.对象里的方法function能够省略

三.函数中的默许参数

4.template

伍.箭头函数

六.进展操作符

柒.解构赋值

8.Symbol

玖.class 模拟类,但实质是根据原型的

10.for …of

1一.promise 化解回调金字塔.回调鬼世界

1二.生成器函数,可以退出函数

13.JS模块化

官方网址:

进程

新兴,微软经过IE制伏了Netscape后一统桌面,结果几年岁月,浏览器毫无进步。(200一年出产的古旧的IE
6到今齐齐哈尔例有人在运用!)

NodeJS:

一.node.js支付环境搭建

二.npm nodejs包管理器

叁.CommonJS模块化标准化,英特尔(require)

四.导出模块/加载模块

Node.js 是三个基于Chromev八 JavaScript 运维时确立的贰个阳台,
用来便宜地搭建神速的, 易于扩大的网络应用· Node.js 借助事件驱动, 非阻塞
I/O 模型变得轻量和快捷

 

从未竞争就一贯不前进。微软认为IE六浏览器已经越发周密,大约未有可改良之处,然后解散了IE陆开发共青团和少先队!而谷歌却觉得帮衬现代Web应用的新一代浏览器才刚好起步,越发是浏览器负责运营JavaScript的外燃机品质还可提高10倍。

fs模块(读写文件)

var fs = require(“fs”);//加载模块

//异步读取文件

fs.readFile(“./readme.txt”,”utf8″, (err, data) => {

nodejs和vue的那个事。if(err) throw err;

console.log(data);

});

//同步读取文件 Synchrous

var data = fs.readFileSync(“./readme.txt”,”utf8″);

console.log(data);

//异步写入文件

fs.writeFile(“./test.txt”, “This is test content~~~”,(err) => {

if(err)throw err;

console.log(“写入成功”);

})

console.log(“write”);

//同步写入文件

fs.writeFileSync(“./test.txt”, “This is test content~~~”);

console.log(“write”);

查看路径消息stat:fs.stat(path, (err, stat) => {})

fs.stat(“./test”, (err, stat) => {

if(err) throw err;

console.log(stat);

if(stat.isFile()) {

console.log(“该路线为文件”);

}else if (stat.isDirectory()) {

console.log(“该路线为文件夹”);

}

})

>2特点

1.process.argv 用于获取当前进程信息

率先Mozilla借助已壮烈就义的Netscape遗产在二零零一年出产了Firefox浏览器,紧接着Apple于200三年在开源的KHTML浏览器的根底上推出了WebKit内核的Safari浏览器,不过仅限于Mac平台。

path模块

var path = require(“path”); //加载模块

path.dirname(url) 获取目录名

path.extname(url)获取后缀名

path.join([…paths]) 拼接路径

var url = “”;

var p1 = path.basename(url,”.html”);

console.log(p1); //path

var p2 = path.dirname(url);

console.log(p2); //

var p3 = path.extname(url);

console.log(p3); //.html

var p4 = path.join(__dirname, “./a”, “../b”, “c”);

console.log(p4); //E:\node\nodejs_2\b\c

\一. 它是叁个Javascript运维条件

 

随后,谷歌(Google)也起初创建本人的浏览器。他们也心情舒畅了Web基特内核,于是基于WebKit内核推出了Chrome浏览器。

querystring模块 查询字符串

var qs = require(“querystring”);

var o = {

color: “red”,

border: “1px solid red”,

“font-size”: “16px”

}

var ret = qs.stringify(o, “;”, “:”);

console.log(ret);

// “color:red;border: 1px solid red;font-size: 16px”

\二. 凭借于Chrome V八引擎进行代码解释

0--node.exe的目录
1--js文件的目录
2--第一个参数

process.argv.slice(2) 获取从第一个参数开始的参数



2.process.env 获取当前系统的环境变量



3.process.stdout.write('xxx')

console.log('xxx') = process.stdout.write('xxx\n');

4.process.stdin.on('data',function(data){

   process.stdout.write(data);
})
//回车时触发


传统的java,.net遇到阻塞io时会创建新的线程来处理。 node内部实现其实也是多线程的,(通过线程池)
//
多线程都是‘假’的,对于一个cpu核心。创建线程需要时间,线程数量有限,cpu在不同线程间切换需要转换上下文,耗费时间
多线程的意义并不大(多核心cpu则可能会提升效率)


node的主线程————事件队列与事件循环圈。

Chrome浏览器是跨Windows和Mac平台的,并且,Google认为要运维现代Web应用,浏览器必须有1个天性特别强大的JavaScript引擎,于是谷歌(Google)本人付出了2个高质量JavaScript引擎,名字叫V8,以BSD许可证开源。

http模块

var http = require(“http”); //加载模块

var server = http.createServer((request, response) => {

//创造三个web服务器

//request

//response

//设置响应头

console.log(request.url);

switch(request.url) {

             case “/”:

                    response.write(“首页”);

                     break;

case “/list”:

response.write(“列表页”);

break;

case “/detail”:

response.write(“详情页”);

break;

}

response.writeHead(200, {

“Content-Type”:”text/html; charset=utf8″

})

response.end();

//if(request.url)

})

//http80端口号 ftp23端口号

server.listen(3000, function() {

console.log(“server has started at port 3000”);

})

\3. 事件驱动

4858美高梅 1

现代浏览器大战让微软的IE浏览器远远地倒退了,因为她俩解散了最有经历、战斗力最强的浏览器团队!回过头再追赶却发现,匡助HTML五的WebKit已经变成手提式有线电话机端的标准了,IE浏览器从此与主流移动端设备绝缘。

一.http请求页面,不是该文件目录下的页面重定向,其他的根据目录查找

var http = require(“http”); //CommonJS规范 加载模块

var fs = require(“fs”);

var path = require(“path”);

var server = http.Server(); //创造服务器

server.on(“request”, function(req, res) {

var filepath = path.join(__dirname, “./www”, req.url);

if(req.url === “/”) {

filepath = path.join(filepath, “index/html”);

}

try{

var stat = fs.statSync(filepath);

if(stat.isFile()) {

var content = fs.readFileSync(filepath);

res.setHeader(“Content0length”, Buffer.bytelength(content))

res.write(content);

}else if(stat.isDirectory() {

//当请求的路线是目录的时候

})

}catch(e) {

//重定向301(永久) 302(暂时)

res.writeHead(302, {

“Location” : “/”

})

}

res.end();

})

server.listen(3000, function() {

console.log(“server has started”);

})

\4. 非阻塞I/O

 

浏览器大战和Node有什么关联?

http协议:

HyperText Transport Protocol)是超文本传输协议的缩写.

http请求:get/post/put/delete(get在地址栏,传输速度快,大小有限制.在头,只好传输壹些文书;post加密传输,在正文)

能够发起http请求的秘诀:浏览器/postman/curl/Fiddle/php/node.js

http一.0和http一.壹的差别:1.0是历次请求都成立一个连连,而1.一是多个请求三个连接.

报文:请求头(post有content-type:”application-x-www-form-urlencoded”,
cookie)+正文

xhr.readystate

XMLHttpRequest.UNSENT  0        开始化连接

XMLHttpRequest.OPENED  1        连接建立

XMLHttpRequest.HEADER_RECEIVED 贰  接收到请求头

XMLHttpRequest.LOADING  叁        处理数量

XMLHttpRequest.DONE    四        处理达成

xhr.status HTTP响应状态码

一起始  十一 切换协议

2开头  成功  200

3开头  重定向  304 301/302

四开端  客户端错误  40四 40三

伍初叶  服务器端错误

\五. 轻量、可伸缩,适于实时数据交互使用

 

话说有个叫RyanDahl的歪果仁,他的办事是用C/C++写高品质Web服务。对于高品质,异步IO、事件驱动是基本尺度,不过用C/C++写就太难受了。于是那位老兄开始考虑用高档语言开发Web服务。他评估了很三种高级语言,发现许多语言固然还要提供了壹同IO和异步IO,不过开发职员壹旦用了1道IO,他们就再也无意写异步IO了,所以,最后,Ryan瞄向了JavaScript。

2.爬虫 cheerio

规律: 一.拉取页面(字符串)http.get/request(node),file_get_content(php)

二.利用模块,方便神速筛选.cheerio(node), simple.html.dom.php(php)

叁.收集音信

npm install cheerio //安装cheerio模块

npm init

// spider.js

var http    = require(“http”);

var cheerio = require(“cheerio”);

var fs      = require(“fs”);

\6. 单进程,单线程

 

因为JavaScript是单线程执行,根本无法开始展览协同IO操作,所以,JavaScript的那一“缺陷”导致了它只可以利用异步IO。

三.express 基于 Node.js 平台,飞快、开放、极简的 web 开发框架。

nmp install express -g

npm install express-generator -g(飞快创建express的完全目录)

express -h

express myapp

cd myapp

npm start

express

一.新建文件夹

cd到该文件目录下

npm init (enter name:myapp enter….)

npm install express

在myapp里面新建app.js

在app.js里面写代码

var express  = require(“express”),//加载express模块

http = require(“http”), //加载http模块

app  = express(), //成立3个express实例

server  = http.createServer(app); //app能够视作http创制服务器的回调函数

//静态能源挂载,设置静态财富目录

//中间件 express.static

//挂载中间件 使用use

app.use(express.static(“public”));

//定义2个到手访问用户IP的中间件

//哪个先挂载,先利用哪个的代码

var ips = [];

function getIp(req, res, next) {

console.log(req.ip);

ips.push(req.ip);

next();

}

function responseIP (req, res, next) {

res.send(req.ip);

}

app.use((req, res, next) => {

console.log(“hello”);

next();

})

app.use(getIp);

app.use(responseIP);

app.get(“/”, (req, res) => {

res.send(“首页”);

})

app.get(“/list”, (req, res) => {

// console.log(req.ip);获取ip

res.send(“列表页”);

})

app.get(“/details”, (req, res) => {

res.send(“详情页”);

})

server.listen(3000, function() {

//监听端口号2000,并提示服务成功开启

console.log(“Server has started”);

})

总计express:中间件和路由.

>3NodeJS的优缺点

模块**
**

选定了支出语言,还要有运维时引擎。那位老兄曾想念过本身写贰个,但是精明地舍弃了,因为V八便是开源的JavaScript引擎。让谷歌投资去优化V捌,咱只负责改造一下拿来用,还不用付钱,这些购销很合算。

三.websocket 营造实时应用(你猜笔者画,录像直播)

全双工、双向数据、长连接的商谈,h5新增性情

劳务器端能够积极向浏览器端发送新闻

不能够不浏览器要扶助,服务器要帮助,数据传输格式是Frame

进度:第3回是由客户端发起,请求的报文的伸手头会多一些内容,须要服务器更换协议.

服务器端响应回报文,响应头也会多几条数据,之后就能建立长的连接.

a. 发起呼吁,跟壹般的http请求例外的地点,

请求头 包括:

Sec-WebSocket-Key:asgK0L1sVa22xbiq8MU58w==

Sec-WebSocket-Version:13

Upgrade:websocket

让服务器更新切换协议 websocket

b. 服务器收到请求,upgrade

透过一定的步子算法 产生

Sec-WebSocket-Accept:IQcF4EGKE8sALj3PxJRvYQ1iG2Y

2.  npm init

npm install socketio express –save-dev

优点:

 

于是在200八年,Ryan正式生产了基于JavaScript语言和V八引擎的开源Web服务器项目,命名字为Node.js。尽管名字很土,可是,Node第三遍把JavaScript带入到后端服务器开发,加上世界七月经有那3个的JavaScript开发职员,所以Node一下子就火了起来。

socketio 是对websocket协商封装的1个模块,让客户端和服务器端的写法都以一模一样的

socket.emit()发数据

socket.on()收数据

监听客户端连接,回调函数会传送此番连接的socket

io.on(‘connection’,function(socket));

给全体客户端广播音信

io.sockets.emit(‘String’,data);

给钦命的客户端发送音信

io.sockets.socket(socketid).emit(‘String’, data);

监听客户端发送的音信

socket.on(‘String’,function(data));

给该socket的客户端发送音讯

socket.emit(‘String’, data);

3.WebSocket

new Websocket(“ws:localhost/chat”)

一. 高并发(最要紧的优点)

exports的实现:

在Node上运转的JavaScript比较其余后端开发语言有啥优势?

gulp

npm init

npm install gulp –save-dev

新建 gulpfile.js(暗许执行的公文)

//gulpfile.js

//一.陈设任务, 二.自行执行

var gulp = require(“gulp”);

var uglify = require(“gulp-uglify”);

//task1 概念贰个职务ufligy 压缩js

gulp.task(“uglify” ,function() {

gulp.src(“./src/js/*.js”)

.pipe(uglify())

.pipe(gulp.dest(“./dist/js”))

})

安装gulp-uglify插件 npm install gulp-uglify –save-dev

新建src文件夹 > js文件夹 >demo.js

新建dist文件夹> js文件夹 >

运行 gulp uglify

下一场在dist文件夹就能找到已经压缩的demo.js

插件:gulp-less

插件:gulp-minify-css

//文件看守, 监听./src/less/*.less 文件的变动,变化运转该less任务

gulp.task(“default”, [“uglify”, “less”], function() {

gulp.watch(“./src/less/*.less”, [“less”]);

})

//运营 gulp即可虽然改变代码

\2. 符合I/O密集型应用

 

最大的优势是借助JavaScript天生的事件驱动机制加V八高品质引擎,使编写高品质Web服务易如反掌。

webpack

全局安装webpack npm install webpack –save-dev

新建文件夹webpack

壹.发轫化多少个连串 npm init

name:不能为webpack

二.在该文件夹上面设置npm install webpack –save-dev

  1. webpack 财富模块化

webpack ./app/main.js ./app/bundle.js

  1. mongodb 非关系型数据库

mongoose Nodejs操作mongodb数据库的模块

缺点:

module是概念在.js文件中的对象

附带,JavaScript语言本身是完善的函数式语言,在前端开发时,开发职员往往写得比较随意,令人感觉JavaScript就是个“玩具语言”。不过,在Node环境下,通过模块化的JavaScript代码,加上函数式编制程序,并且无需思虑浏览器包容性难题,直接动用最新的ECMAScript
陆标准,可以完全满意工程上的需求。

一.
不相符CPU密集型应用;CPU密集型应用给Node带来的挑衅首尽管:由于JavaScript单线程的原由,若是有长日子运作的一个钱打二十五个结(比如大循环),将会导致CPU时间片无法释放,使得后续I/O不能发起;

xxx.js

本身还听别人说过io.js,那又是怎么鬼?

缓解方案:分解大型运算职分为多个小义务,使得运算能够及时释放,不阻塞I/O调用的发起;

console.log(module)

因为Node.js是开源项目,即便由社区后浪推前浪,但骨子里径直由Joyent公司援助。由于一批开发者对Joyent集团的方针不满,于201四年从Node.js项目fork出了io.js项目,决定独立发展,但双边其实是合作的。

\二. 只协助单核CPU,不可能丰盛利用CPU

….(打印出module对象)

只是中夏族民共和国有句古话,叫做“分久必合,合久必分”。分家后没多短期,Joyent集团代表要和解,于是,io.js项目又控制回归Node.js。

\三. 可信性低,一旦代码某些环节崩溃,整个系列都完蛋

 

具体做法是今后io.js将第一添加新的表征,假设我们测试用得爽,就把新特色参加Node.js。io.js是“尝鲜版”,而Node.js是线上稳定版,也正是Fedora
Linux和BMWX伍HEL的关联。

原因:单进程,单线程

module中有1个exports对象,能够向内添加属性和办法

安装Node.js和npm

>4. 适合NodeJS的场景

(参考

是因为Node.js平台是在后端运维JavaScript代码,所以,必须首先在本机安装Node环境。

\1. RESTful API

 

安装Node.js

那是NodeJS最理想的行使场景,能够处理数万条连接,自身并没有太多的逻辑,只要求请求API,组织数量举行再次回到即可。它实质上只是从某些数据库中找找一些值并将它们构成一个响应。由于响应是为数不多文件,入站请求也是为数不多的文件,由此流量不高,一台机器甚至也足以处理最困苦的合营社的API须求。

 

近日Node.js的流行版本是陆.二.x。首先,从Node.js官网下载对应平台的安装程序,网速慢的童鞋请移步国内镜像。

\2. 统一Web应用的UI层

写一个require的实现:

在Windows上安装时务必选取1切组件,包涵勾选Add to Path。

当下MVC的架构,在某种意义上的话,Web开发有两个UI层,1个是在浏览器里面大家最终见到的,另三个在server端,负责生成和拼接页面。

 

安装达成后,在Windows环境下,请打开命令提示符,然后输入node
-v,如若设置符合规律,你应当看到v陆.二.0这么的输出:

不斟酌那种架构是好是坏,不过有此外壹种实施,面向服务的架构,越来越好的做上下端的注重分离。要是全部的要紧作业逻辑都封装成REST调用,就代表在上层只供给思量如何用那个REST接口创设具体的选取。那个后端程序员们一贯不担心具体数目是什么样从3个页面传递到另三个页面包车型地铁,他们也不用管用户数量更新是透过Ajax异步获取的依旧经过刷新页面。

function $require(id){

C:\Users\IEUser>node -vv6.2.0

\三. 恢宏Ajax请求的选用

 

一连在命令提示符输入node,此刻你将跻身Node.js的互动环境。在互相环境下,你能够输入任意JavaScript语句,例如100+200,回车后将收获输出结果。

诸如天性化应用,每种用户观望的页面都不1样,缓存失效,要求在页面加载的时候发起Ajax请求,NodeJS能响应大量的出现请求。  简单来讲,NodeJS适合利用在高并发、I/O密集、少量作业逻辑的现象。

const fs = require(‘fs’);

要退出Node.js环境,连按一次Ctrl+C。

Ryan dahl对node.js初衷

二〇〇八年,小编在查找1个新的编制程序平台来做网址。小编并不是想要壹门新的言语,实际上,语言本身的细节对笔者的话并不重大。作者确实关切的是,该语言是或不是提供先进的推送功效并集成到网址中来,仿佛本身在Gmail中看看的那么——能够从服务器端把数量主动推送给用户,而不是采取不断轮询拉取数据的诀要。现有的平台都把服务器作为接受请求然后回到相应内容的配备。要把事件推送到浏览器,平台需求可以不断处理大批量开拓的互联网连接,而那之中有不少接连其实是悠闲的。

自笔者通晓怎么着使用系统调用(用C)达成那样的功力。假使只行使非阻塞式socket,每一个连接的支付都会十分的小。在小范围测试中,小编得以演示壹台服务器,它能同时处理几千个闲置连接,或促成一点都不小的吞吐量。笔者知道那是在Unix服务器上用户空间程序能够达成的最优操作了。不过,小编并不想使用C,笔者须求的是1种名牌产品特产产品新品优质产品Smart活的动态语言。假若急需,作者得以在每一种编制程序语言中都用壹模一样的系统调用,但那样做尤其难看,而且那只是socket编制程序的“替代”方法而已。作者觉得,非阻塞socket编制程序并非那么难堪,只要任何都做成非阻塞的就能够完结了。

于是乎,作者有了个意见:JavaScript结合非阻塞socket!因为JavaScript并不曾现成的socket库,所以本身得以勇做第1人,来推举那一个全新且大有前途的接口。只要把V8接上笔者的非阻塞C代码,作者就能把它成功。小编终止了当下承接的行事,起初大力完毕这几个想法。当笔者编写好并宣布了初期的版本后,立刻就有用户初步反馈bug,然后我起来不停地处理这个bug,就那样,不知不觉离世了三年。

实践申明,JavaScript与非阻塞socket同盟得一定周到。起头自小编并不敢肯定那或多或少,但闭包让具备事务变得只怕。只供给简单的几行JavaScript代码,就能够营造出格外复杂的非阻塞服务器。笔者最初还操心,系统会过度小众,但相当慢小编就放心了,因为世界外市的黑客们纷纷开端为其编写制定造进程序库。唯一的风浪循环队列和纯粹的非阻塞接口让程序库不必扩展昂贵的线程,就能添加更多的扑朔迷离功能。

在Node中,用户会意识系统在私下认可情状下就能很好地扩大。因为其基本系统做出的取舍是,不一致意系统中的任何部分做出太坏的工作来(比如堵塞当前线程),所以总体品质也不会太差。假诺以能够处理的流量作为总括,Node的艺术要比守旧的阻塞式操作好上1个多少级。

如今,Node已经在全球被广大店铺所运用,包蕴创业集团、Voxer、Uber,以及沃尔玛、微软那般的显赫公司。能够说,每一天通过Node处理的请求数以亿计。随着越来越多的人踏足到本项目中来,可用的第1方模块和扩充拉长迅猛,而且品质也不止晋升。固然自个儿曾提出将Node用于重大任务使用,但最近,即就是讲求最苛刻的服务器系统,笔者也会真心地推荐使用Node。

>5.commonjs

一.怎么着定义三个自定义的模块

五个文本就是多少个模块 a.js 文件名正是模块
a

二.模块中能放那几个东西

* function class variable*

Node,CommonJS,浏览器依旧是W3C之间有哪些关系:

  |—————浏览器—– ——————|      
 |————————–CommonJS———————————-|

 

  |  BOM  |       | DOM |        | ECMAScript |         | FS |          
| TCP |         | Stream |        | Buffer |          |……..|

 

  |——-W3C———–|      
|—————————————Node————————————————–|

CommonJS定义的模块分为:{模块引用(require)} {模块定义(exports)}
{模块标识(module)}

 

require()用来引进外部模块;exports对象用于导出当前模块的章程或变量,唯一的导出口;module对象就象征模块本身。

 //sum.js

 exports.sum = function(){…做加操作..};

 

 //calculate.js

 var math = require(‘sum’);

exports.add = function(n){

    return math.sum(val,n);

 };

 

CommonJS定义的模块分为:{模块引用(require)} {模块定义(exports)}
{模块标识(module)}

 

require()用来引进外部模块;exports对象用于导出当前模块的措施或变量,唯1的导出口;module对象就象征模块本人。

 //sum.js

 exports.sum = function(){…做加操作..};

 

 //calculate.js

 var math = require(‘sum’);

exports.add = function(n){

    return math.sum(val,n);

 };

 

二、AMD

 

CommonJS是重中之重为了JS在后端的表现制定的,他是不切合前端的,为啥这么说吗?

 

这亟需分析一下浏览器端的js和服务器端js都主要做了怎么着事,有哪些两样了:

 

 

 

—————————————服务器端JS   |  
 浏览器端JS——————————————-

 

                                   相同的代码必要反复执行  |  
 代码必要从一个服务器端分发到八个客户端执行

 

                                     CPU和内存能源是瓶颈   |  
 带宽是瓶颈

 

                                        加载时从磁盘中加载   |  
 加载时索要经过互连网加载

 


 

 

 

于是,英特尔(异步模块定义)出现了,它就首要为前端JS的变现制定正规。

 

英特尔就唯有二个接口:define(id?,dependencies?,factory);

 

它要在宣称模块的时候制定具有的依赖(dep),并且还要作为形参传到factory中,像那样:

 

 

 

 define([‘dep1′,’dep2’],function(dep1,dep2){…});

 

 

define(function(){

     var exports = {};

     exports.method = function(){…};

     return exports;

 });

 

const path = require(‘path’);

在Mac或Linux环境下,请打开终端,然后输入node -v,你应该看到如下输出:

概述

Node 应用由模块组成,采取 CommonJS 模块规范。

种种文件正是3个模块,有谈得来的作用域。在二个文书之中定义的变量、函数、类,都以私家的,对别的文件不可知。

// example.js
var x = 5;
var addX = function (value) {
  return value + x;
};

位置代码中,变量x和函数addX,是时下文件example.js村办的,别的文件不可知。

一旦想在五个公文分享变量,必须定义为global目的的习性。

global.warning = true;

地点代码的warning变量,能够被全体文件读取。当然,那样写法是不引入的。

CommonJS规范规定,每一个模块内部,module变量代表当前模块。这么些变量是一个目的,它的exports属性(即module.exports)是对外的接口。加载有个别模块,其实是加载该模块的module.exports属性。

var x = 5;
var addX = function (value) {
  return value + x;
};
module.exports.x = x;
module.exports.addX = addX;

地点代码通过module.exports出口变量x和函数addX

require主意用于加载模块。

var example = require('./example.js');

console.log(example.x); // 5
console.log(example.addX(1)); // 6

require艺术的详实表明参见《Require命令》壹节。

CommonJS模块的特征如下。

  • 怀有代码都运转在模块功用域,不会传染全局效能域。
  • 模块能够屡屡加载,不过只会在第2回加载时运维一回,然后运行结果就被缓存了,以往再加载,就径直读取缓存结果。要想让模块再度运营,必须化解缓存。
  • 模块加载的各个,依照其在代码中冒出的逐条。

 

$ node -vv6.2.0

module对象

Node内部提供二个Module创设函数。全体模块都是Module的实例。

function Module(id, parent) {
  this.id = id;
  this.exports = {};
  this.parent = parent;
  // ...

每一种模块内部,都有3个module目的,代表当前模块。它有以下属性。

  • module.id 模块的识别符,平时是含有相对路径的模块文件名。
  • module.filename 模块的文件名,带有绝对路径。
  • module.loaded 重回二个布尔值,表示模块是还是不是早已完毕加载。
  • module.parent 重返叁个目的,表示调用该模块的模块。
  • module.children 再次来到一个数组,表示该模块要用到的别的模块。
  • module.exports 表示模块对外出口的值。

下面是1个演示文件,最后1行输出module变量。

// example.js
var jquery = require('jquery');
exports.$ = jquery;
console.log(module);

推行那一个文件,命令行会输出如下消息。

{ id: '.',
  exports: { '$': [Function] },
  parent: null,
  filename: '/path/to/example.js',
  loaded: false,
  children:
   [ { id: '/path/to/node_modules/jquery/dist/jquery.js',
       exports: [Function],
       parent: [Circular],
       filename: '/path/to/node_modules/jquery/dist/jquery.js',
       loaded: true,
       children: [],
       paths: [Object] } ],
  paths:
   [ '/home/user/deleted/node_modules',
     '/home/user/node_modules',
     '/home/node_modules',
     '/node_modules' ]
}

假如在指令行下调用有个别模块,比如node something.js,那么module.parent就是null。假如是在本子之中调用,比如require('./something.js'),那么module.parent即便调用它的模块。利用那或多或少,能够断定当前模块是或不是为输入脚本。

if (!module.parent) {
    // ran with `node something.js`
    app.listen(8088, function() {
        console.log('app listening on port 8088');
    })
} else {
    // used with `require('/.something.js')`
    module.exports = app;
}

const filename = path.join(__dirname,id);

即使版本号不是v陆.2.x,表明Node.js版本不对,后边章节的代码不保险能平时启动,请重新安装最新版本。

module.exports属性

module.exports属性表示近来模块对外输出的接口,别的文件加载该模块,实际上正是读取module.exports变量。

var EventEmitter = require('events').EventEmitter;
module.exports = new EventEmitter();

setTimeout(function() {
  module.exports.emit('ready');
}, 1000);

地点模块会在加载后1秒后,发出ready事件。其余文件监听该事件,可以写成上面那样。

var a = require('./a');
a.on('ready', function() {
  console.log('module a is ready');
});

 

npm

exports变量

为了便于,Node为每一种模块提供二个exports变量,指向module.exports。那等同在每个模块底部,有一行那样的命令。

var exports = module.exports;

造成的结果是,在对外输出模块接口时,能够向exports对象添加方法。

exports.area = function (r) {
  return Math.PI * r * r;
};

exports.circumference = function (r) {
  return 2 * Math.PI * r;
};

专注,无法一贯将exports变量指向两个值,因为这么等于隔离了exportsmodule.exports的联系。

exports = function(x) {console.log(x)};

上边那样的写法是不行的,因为exports不再指向module.exports了。

下边包车型大巴写法也是行不通的。

exports.hello = function() {
  return 'hello';
};

module.exports = 'Hello world';

上边代码中,hello函数是心有余而力不足对外出口的,因为module.exports被再一次赋值了。

那代表,如若3个模块的对外接口,正是八个拾足的值,不能运用exports输出,只能利用module.exports输出。

module.exports = function (x){ console.log(x);};

假设你以为,exportsmodule.exports时期的分别很难分清,3个简约的处理情势,就是吐弃行使exports,只使用module.exports

$require.cache = $require.cache || {};

在正规启幕Node.js学习在此之前,大家先认识一下npm。

英特尔规范与CommonJS规范的包容性

CommonJS规范加载模块是手拉手的,也等于说,只有加载成功,才能执行后边的操作。英特尔规范则是非同步加载模块,允许钦点回调函数。由于Node.js首要用来服务器编制程序,模块文件1般都曾经存在于地点硬盘,所以加载起来比较快,不用思念非同步加载的不2诀要,所以CommonJS规范相比适用。不过,假若是浏览器环境,要从服务器端加载模块,那时就不能够不选用非同步格局,由此浏览器端1般选取英特尔规范。

英特尔规范行使define方法定义模块,上面正是1个例子:

define(['package/lib'], function(lib){
  function foo(){
    lib.log('hello world!');
  }

  return {
    foo: foo
  };
});

速龙规范允许输出的模块包容CommonJS规范,那时define办法必要写成上边那样:

define(function (require, exports, module){
  var someModule = require("someModule");
  var anotherModule = require("anotherModule");

  someModule.doTehAwesome();
  anotherModule.doMoarAwesome();

  exports.asplode = function (){
    someModule.doTehAwesome();
    anotherModule.doMoarAwesome();
  };
});

if($require.cache[filename]){

npm是哪些东东?npm其实是Node.js的包管理工具(package manager)。

require命令

 return $require.cache[filename].exports;

缘何大家要求二个包管理工科具呢?因为大家在Node.js上付出时,会用到广大外人写的JavaScript代码。若是大家要利用别人写的有个别包,每一趟都依据名称搜索一下官方网址,下载代码,解压,再使用,非凡麻烦。于是二个集中管理的工具应运而生:大家都把温馨费用的模块打包后放置npm官网上,要是要利用,直接通过npm安装就能够间接用,不用管代码存在哪,应该从哪下载。

主导用法

Node使用CommonJS模块规范,内置的require一声令下用于加载模块文件。

require一声令下的基本成效是,读入并履行一个JavaScript文件,然后再次回到该模块的exports对象。假如未有察觉钦赐模块,会报错。

// example.js
var invisible = function () {
  console.log("invisible");
}

exports.message = "hi";

exports.say = function () {
  console.log(message);
}

运转下边包车型地铁一声令下,能够输出exports对象。

var example = require('./example.js');
example
// {
//   message: "hi",
//   say: [Function]
// }

万1模块输出的是3个函数,那就不能够定义在exports对象方面,而要定义在module.exports变量上边。

module.exports = function () {
  console.log("hello world")
}

require('./example2.js')()

地方代码中,require命令调用本人,等于是实施module.exports,因而会输出
hello world。

}

更关键的是,借使我们要选择模块A,而模块A又凭借于模块B,模块B又凭借于模块X和模块Y,npm能够依照依赖关系,把具备重视的包都下载下来并保管起来。不然,靠大家安危与共手动管理,肯定既麻烦又便于出错。

加载规则

require命令用于加载文件,后缀名暗许为.js

var foo = require('foo');
//  等同于
var foo = require('foo.js');

听他们讲参数的比不上格式,require一声令下去分歧途径寻找模块文件。

(1)借使参数字符串以“/”开端,则代表加载的是一个位居相对路径的模块文件。比如,require('/home/marco/foo.js')将加载/home/marco/foo.js

(贰)要是参数字符串以“./”初步,则象征加载的是三个位居相对路径(跟当前施行脚本的职位比较)的模块文件。比如,require('./circle')将加载当前剧本同一目录的circle.js

(三)若是参数字符串不以“./“或”/“开始,则表示加载的是三个暗中认可提供的为主模块(位于Node的系统设置目录中),只怕一个位居各级node_modules目录的已设置模块(全局安装或部分安装)。

举例来说,脚本/home/user/projects/foo.js执行了require('bar.js')指令,Node会依次搜索以下文件。

  • /usr/local/lib/node/bar.js
  • /home/user/projects/node_modules/bar.js
  • /home/user/node_modules/bar.js
  • /home/node_modules/bar.js
  • /node_modules/bar.js

那样设计的目标是,使得不一样的模块能够将所依靠的模块本地化。

(四)假若参数字符串不以“./“或”/“起头,而且是二个途径,比如require('example-module/path/to/file'),则将先找到example-module的职分,然后再以它为参数,找到继承路径。

(5)假如内定的模块文件并没有意识,Node会尝试为文件名添加.js.json.node后,再去摸索。.js件会以文本格式的JavaScript脚本文件分析,.json文本会以JSON格式的文本文件分析,.node文件会以编写翻译后的2进制文件分析。

(陆)要是想获得require一声令下加载的稳妥文件名,使用require.resolve()方法。

 

讲了如此多,npm毕竟在哪?

目录的加载规则

普通,大家会把有关的文件会放在叁个目录里面,便于组织。那时,最佳为该目录设置三个入口文件,让require主意能够通过那么些进口文件,加载整个目录。

在目录中放置三个package.json文件,并且将进口文件写入main字段。上边是贰个事例。

// package.json
{ "name" : "some-library",
  "main" : "./lib/some-library.js" }

require发觉参数字符串指向1个索引之后,会自动查看该目录的package.json文件,然后加载main字段钦点的进口文件。就算package.json文本并未有main字段,只怕根本就不曾package.json文本,则会加载该目录下的index.js文件或index.node文件。

const dirname = path.dirname(filename);

骨子里npm已经在Node.js安装的时候顺便装好了。我们在命令提醒符可能极端输入npm
-v,应该看到类似的输出:

模块的缓存

首先次加载有些模块时,Node会缓存该模块。以往再加载该模块,就一向从缓存取出该模块的module.exports属性。

require('./example.js');
require('./example.js').message = "hello";
require('./example.js').message
// "hello"

上边代码中,一连三次利用require指令,加载同多个模块。第一遍加载的时候,为出口的对象添加了二个message质量。可是第2遍加载的时候,那一个message属性仍旧存在,那就证实require命令并未重新加载模块文件,而是输出了缓存。

只要想要数十二次进行有些模块,能够让该模块输出贰个函数,然后每一趟require其一模块的时候,重新履行一下输出的函数。

富有缓存的模块保存在require.cache里头,如果想删除模块的缓存,能够像上边那样写。

// 删除指定模块的缓存
delete require.cache[moduleName];

// 删除所有模块的缓存
Object.keys(require.cache).forEach(function(key) {
  delete require.cache[key];
})

留意,缓存是依照相对路径识别模块的,假设相同的模块名,但是保存在分裂的门路,require命令依旧会再也加载该模块。

 

C:\>npm -v3.8.9

环境变量NODE_PATH

Node执行一个本亥时,会先查看环境变量NODE_PATH。它是一组以冒号分隔的相对路径。在任何地方找不到钦命模块时,Node会去这几个途径查找。

可以将NODE_PATH添加到.bashrc

export NODE_PATH="/usr/local/lib/node"

就此,假设蒙受复杂的相对路径,比如上边那样。

var myModule = require('../../../../lib/myModule');

有三种缓解方法,一是将该文件参与node_modules目录,贰是修改NODE_PATH环境变量,package.json文本能够应用上边包车型大巴写法。

{
  "name": "node_path",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "NODE_PATH=lib node index.js"
  },
  "author": "",
  "license": "ISC"
}

NODE_PATH是历史遗留下来的3个门路化解方案,平日不应当利用,而应该利用node_modules目录机制。

let code = fs.readFileSync(filename,’utf8′);

就算一贯输入npm,你会看出类似上边包车型大巴输出:

模块的循环加载

壹旦爆发模块的循环加载,即A加载B,B又加载A,则B将加载A的不完整版本。

// a.js
exports.x = 'a1';
console.log('a.js ', require('./b.js').x);
exports.x = 'a2';

// b.js
exports.x = 'b1';
console.log('b.js ', require('./a.js').x);
exports.x = 'b2';

// main.js
console.log('main.js ', require('./a.js').x);
console.log('main.js ', require('./b.js').x);

地点代码是多个JavaScript文件。当中,a.js加载了b.js,而b.js又加载a.js。那时,Node再次回到a.js的不完全版本,所以举行结果如下。

$ node main.js
b.js  a1
a.js  b2
main.js  a2
main.js  b2

修改main.js,再一次加载a.js和b.js。

// main.js
console.log('main.js ', require('./a.js').x);
console.log('main.js ', require('./b.js').x);
console.log('main.js ', require('./a.js').x);
console.log('main.js ', require('./b.js').x);

实践上边代码,结果如下。

$ node main.js
b.js  a1
a.js  b2
main.js  a2
main.js  b2
main.js  a2
main.js  b2

地点代码中,第一次加载a.js和b.js时,会直接从缓存读取exports属性,所以a.js和b.js内部的console.log语句都不会实施了。

let module = { id:filename,exports:{} };

C:\> npmUsage: npm where is one of: …

require.main

require办法有1个main性格,能够用来判断模块是直接执行,如故被调用执行。

间接实施的时候(node module.js),require.main品质指向模块自身。

require.main === module
// true

调用执行的时候(通过require加载该脚本执行),下边包车型地铁表明式重返false。

let exports = module.exports;

上面包车型大巴一大堆文字告诉您,npm须要跟上命令。今后大家不用关注那几个命令,前面会相继讲到。近日,你只需求确定保证npm正确安装了,能运转就行。

模块的加运载飞机制

CommonJS模块的加运载飞机制是,输入的是被输出的值的正片。相当于说,一旦输出二个值,模块内部的转变就影响不到这些值。请看上边这么些例子。

上面是二个模块文件lib.js

// lib.js
var counter = 3;
function incCounter() {
  counter++;
}
module.exports = {
  counter: counter,
  incCounter: incCounter,
};

地点代码输出内部变量counter和改写那些变量的内部方法incCounter

接下来,加载上边的模块。

// main.js
var counter = require('./lib').counter;
var incCounter = require('./lib').incCounter;

console.log(counter);  // 3
incCounter();
console.log(counter); // 3

地点代码表明,counter输出今后,lib.js模块内部的变动就影响不到counter了。

 

第一个Node程序

require的个中处理流程

require一声令下是CommonJS规范内部,用来加载其余模块的授命。它其实不是多少个大局命令,而是指向当前模块的module.require命令,而后人又调用Node的在那之中命令Module._load

Module._load = function(request, parent, isMain) {
  // 1. 检查 Module._cache,是否缓存之中有指定模块
  // 2. 如果缓存之中没有,就创建一个新的Module实例
  // 3. 将它保存到缓存
  // 4. 使用 module.load() 加载指定的模块文件,
  //    读取文件内容之后,使用 module.compile() 执行文件代码
  // 5. 如果加载/解析过程报错,就从缓存删除该模块
  // 6. 返回该模块的 module.exports
};

上边的第五步,选拔module.compile()实施钦定模块的剧本,逻辑如下。

Module.prototype._compile = function(content, filename) {
  // 1. 生成一个require函数,指向module.require
  // 2. 加载其他辅助方法到require
  // 3. 将文件内容放到一个函数之中,该函数可调用 require
  // 4. 执行该函数
};

上边的第1步和第1步,require函数及其协理方法主要如下。

  • require(): 加载外部模块
  • require.resolve():将模块名解析到贰个相对路径
  • require.main:指向主模块
  • require.cache:指向全数缓存的模块
  • require.extensions:依据文件的后缀名,调用不一致的实施函数

一旦require函数准备完成,整个所要加载的台本内容,就被停放贰个新的函数之中,那样可避防止污染全局环境。该函数的参数包涵requiremoduleexports,以及其余部分参数。

(function (exports, require, module, __filename, __dirname) {
  // YOUR CODE INJECTED HERE!
});

Module._compile措施是手拉手执行的,所以Module._load要等它实施到位,才会向用户重回module.exports的值。

4858美高梅 2

require方法接受以下三种参数的传递:

  1. http、fs、path等,原生模块。
  2. ./mod或../mod,绝对路径的文书模块。
  3. /pathtomodule/mod,相对路径的文件模块。
  4. mod,非原生模块的文件模块。
    当require一个文本模块时,从近来文件目录起头查找node_modules目录;然后逐一进入父目录,查找父目录下的
    node_modules目录;依次迭代,直到根目录下的node_modules目录。
    简易,假若require相对路线的文书,查找时不会去遍历各类node_modules目录,其速度最快。其他
    流程如下:
    从module path数组中取出第二个目录作为查找条件。
    一.
    一向从目录中检索该文件,如若存在,则结束查找。固然不设有,则展开下一条搜索。
    二.
    尝试添加.js、.json、.node后缀后查找,即便存在文件,则结束查找。固然不存在,则开始展览下一条。
    三.
    尝试将require的参数作为四个包来进展检索,读取目录下的package.json文件,取得main参数钦点的文件。
  5. 尝试寻找该公文,即便存在,则甘休查找。固然不设有,则开始展览第2条搜索
  6. 万一继续退步,则取出module
    path数组中的下贰个索引作为规范查找,循环第3至5个步骤。
  7. 假设后续战败,循环第二至四个步骤,直到module path中的最终三个值。
  8. 假设依旧退步,则抛出尤其。
    module.exports还是exports
    叁个模块能够透过module.exports或exports将函数、变量等导出,以使别的JavaScript脚本通过require()函数引
    入并动用。
    设若您想你的模块是多少个一定的品类就用module.exports。借使你想的模块是一个一级
    的”实例化对象”就用exports。
    require再次回到的实在是module.exports那个情势,exports其实是指向module.exports的三个引用
    二、Node.js的Path对象
    NodeJS中的Path对象,用于拍卖目录的靶子,升高支付作用。
    用NodeJS的Path命令,与应用Linux下的shell脚本
    命令相似。
    引入path对象:
    var path = require(‘path’);
    比较实用的章程:
  9. path.normalize(p) : 格式化路径
    特点:将不符合规范的路线格式化,简化开发人士中拍卖各类复杂的路子判断
  10. path.join([path1], [path2], […]) : 路径合并
    脾性:将富盛名称用path.seq串联起来,然后用normailze格式化
  11. path.resolve([from …], to) : 路径寻航
    特色:也正是随处的调用系统的cd命令
    示例:
    path.normalize(‘/foo/bar//baz/asdf/quux/..’);
    => ‘/foo/bar/baz/asdf’
    示例:
    path.join(‘///foo’, ‘bar’, ‘//baz/asdf’, ‘quux’, ‘..’);
    =>’/foo/bar/baz/asdf’
  12. path.relative(from, to) : 相对路径
    特征:再次来到有些路径下绝对于另1个路径的相对地点串,相当于:path.resolve(from,
    path.relative(from,
    to)) == path.resolve(to)
  13. path.dirname(p) : 文件夹名称
    特性:再次回到路径的随地的公文夹名称
  14. path.basename(p, [ext]) : 文件名称
  15. path.basename(p, [ext]) : 文件名称
    特征:重临钦点的文书名,再次来到结果可清除[ext]后缀字符串
  16. 扩展名称 path.extname(p)
    示例:
    path.resolve(‘foo/bar’, ‘/tmp/file/’, ‘..’, ‘a/../subfile’)
    //相当于:
    cd foo/bar
    cd /tmp/file/
    cd ..
    cd a/../subfile
    pwd
    示例:
    path.relative(‘C:\\orandea\\test\\aaa’,
    ‘C:\\orandea\\impl\\bbb’)
    =>’..\\..\\impl\\bbb’
    path.relative(‘/data/orandea/test/aaa’, ‘/data/orandea/impl/bbb’)
    =>’../../impl/bbb’
    示例:
    path.dirname(‘/foo/bar/baz/asdf/quux’)
    =>’/foo/bar/baz/asdf’
    示例
    path.basename(‘/foo/bar/baz/asdf/quux.html’)
    =>’quux.html’
    path.basename(‘/foo/bar/baz/asdf/quux.html’, ‘.html’)
    =>’quux’
    特色:重临钦赐文件名的扩展名称
  17. 一定平台的文书分隔符 path.sep
    特色:获取文件路径的分隔符,主要是与操作系统相关
  18. 特定平台的不2秘诀分隔符 path.delimiter
    一定平台的路径分隔符, ‘;‘ 或许 ‘:‘.
    Linux 上的例证:
    Windows 上的事例:
    示例:
    path.extname(‘index.html’)
    =>’.html’
    path.extname(‘index.’)
    =>’.’
    path.extname(‘index’)
    =>”
    示例:
    linux:
    ‘foo/bar/baz’.split(path.sep)
    =>[‘foo’, ‘bar’, ‘baz’]
    window:
    ‘foo\\bar\\baz’.split(path.sep)
    =>[‘foo’, ‘bar’, ‘baz’]
    process.env.PATH.split(path.delimiter)
    // returns
    [‘/usr/bin’, ‘/bin’, ‘/usr/sbin’, ‘/sbin’, ‘/usr/local/bin’]
    console.log(process.env.PATH)
    // ‘C:\Windows\system32;C:\Windows;C:\Program Files\nodejs\’
    process.env.PATH.split(path.delimiter)
    // returns
    [‘C:\Windows\system32’, ‘C:\Windows’, ‘C:\Program
    Files\nodejs\’]
    process.env.PATH.split(path.delimiter)
    // returns
    [‘C:\Windows\system32’, ‘C:\Windows’, ‘C:\Program
    Files\nodejs\’]
    nodejs 全局变量
  19. module.filename:开发时期,该行代码所在的文书。
  20. __filename:始终等于 module.filename。
  21. __dirname:开发期间,该行代码所在的目录。
  22. process.cwd():运转node的办事目录,能够应用 cd /d 修改工作目录。
  23. require.main.filename:用node命令运行的module的filename, 如 node
    xxx,那里的filename便是其一
    xxx。
    require()方法的坐标路径是:module.filename;
    fs.readFile()的坐标路径是:process.cwd()。

异步(async)和同步(sync)
Nodejs中Api壹般都以异步的接口,倘若调用同步的只须要在背后加上xxxSync()。
Node.js 文件系统(fs
模块)模块中的方法均有异步和1道版本,例如读取文件内容的函数有异步的
fs.readFile() 和同步的 fs.readFileSync()。
Node文件系统:目录操作

  1. 认清文件路径是不是留存: fs.exists(path, callback)
    参数表达:
  2. 开创目录 fs.mkdir/mkdirSync(path[, mode], callback)
    var fs = require(“fs”);
    //异步读取文件
    fs.readFile(‘input.txt’, function (err, data) {
    if (err) {
    return console.error(err);
    }
    console.log(“Asynchronous read: ” + data.toString());
    });
    // /同步读取文件
    var data = fs.readFileSync(‘input.txt’);
    console.log(“Synchronous read: ” + data.toString());
    console.log(“Program Ended”);
    path 欲检验的文本路径
    callback 回调
    fs.exists(“test”,function(exists){
    console.log(exists);
    })
    path – 文件路径 ; mode – 设置目录权限,私下认可为077柒 callback – 回调函数
  3. 翻看目录 fs.readdir(path, callback(err, files))
    path – 文件路径。
    callback – 回调函数,回调函数带有七个参数err, files,err
    为错误新闻,files 为 目录下的文书数组列表
    重返结果: [ ‘note.txt’ ]
  4. 除去目录 fs.rmdir(path, callback)
    参数使用表达如下:
    path – 文件路径。 callback – 回调函数,未有参数。
    专注:只可以删除空的目录,有文件的目录会报错:
    [Error: ENOTEMPTY: directory not empty, rmdir
    ‘F:\FullStack-Cource-2017\Nodejs-Laravel-Action\03-
    Node模块-FileSystem\test’]
    Node文件模块:文件操作表明
  5. 写入文件 fs.writeFile(filename, data[, options], callback)
    若果文件存在,写入的始末会覆盖旧文件内容
    参数使用验证如下:
    var fs = require(“fs”);
    fs.mkdir(“test”,function(error){
    if (err) return console.error(err);
    console.log(‘目录创立成功’);
    })
    fs.readdir(“test”,function(error,files){
    console.log(files);
    })
    fs.rmdir(“test”,function(error){
    console.log(error);
    })
  6. 文件读取 fs.readFile( url , code , callback);
  7. 异步读取文件
    fs.readFile(“test/1.txt”,”utf-8″,function(error,data){
    console.log(data); })
  8. 异步读取文件
    var data =fs.readFileSync(“test/1.txt”,”utf-8″); console.log(data);
  9. 向文件中加进写入 fs.appendFile(name,str,encode,callback);
    参数表明:
    name : 文件名 str : 添加的字段 encode : 设置编码 callback :
    回调函数
    栗子
    fs.appendFile(“test/一.txt”,’窗前明月光,疑是地上霜’,’utf八’,function(eror){
    })
  10. 改变文件名 : fs.rename(old文件名,新文件名,callback(传递贰个err
    参数))
    fs.rename(“test/1.txt”,”test/a.txt”,function(error){
    })
  11. 翻看文件状态 fs.stat(fileaddr,callback(error,stats))
    在fs模块中,能够使用 fs.stat() 方法或 fs.lstat()
    方法查看二个文本或目录的音信,如文件的深浅、制造时
    间、权限等消息。那八个法子的唯一差异是当查看符号链接文件的音信时,必须使用
    fs.lstat() 方法。
    var fs = require(“fs”); var path = require(“path”);
    path – 文件路径。
    data – 要写入文件的数目,能够是 String(字符串) 或 Buffer(流) 对象。
    options – 该参数是2个对象,包罗 {encoding, mode, flag}。暗中认可编码为
    utf8, 方式为 066陆 ,flag 为
    ‘w’
    callback –
    回调函数,回调函数只包罗错误新闻参数(err),在写入失利时回来。
    var fs = require(“fs”);
    fs.writeFile(“test/1.txt”,”hello file”,function(error){
    console.log(error);
    })
    var fileaddr = path.resolve(__dirname,”file/note.txt”);
    /**
    * fileaddr: 须要查阅读处理境的相对,或然绝对地址
    fs.Stats对象的法子如下:
    stats.isFile() :
    判断被查看对象是不是是一个文书。即便是标准文件,重返true。是目录、套接字、符号连
    接、或设施等回到false。
    stats. isDirectory() :
    判断被查看对象是或不是是多少个目录。倘诺是目录,再次回到true。
    stats. isBlockDevice() : 判断被翻动对象是或不是是三个块设备文件。
    借使是块设备,再次回到true,当先5/10情状下
    类UNIX系统的块设备都置身/dev目录下。
    stats. isCharacterDevice() :
    判断被查看对象是不是是1个字符设备文件。如果是字符设备,再次来到true。
    stats. isSymbolicLink() :
    判断被翻开对象是或不是是一个标志链接文件。假诺是符号连接,再次来到true。该办法仅
    在fs.lstat()方法的回调函数中有效。
    stats.isFIFO() :
    判断被查看对象是或不是是3个FIFO文件。借使是FIFO,再次来到true。FIFO是UNIX中的一种特殊
    体系的通令管道。该方式仅在LINUX系统下有效。
    stats.isSocket() : 判断被翻开对象是不是是2个socket文件。
    借使是UNIX套接字,重回true。该方法仅在
    LINUX系统下有效。
    fs.Stats对象的品质如下:
    dev : 文件或目录所在的配备ID。该属性值在UNIX系统下有效;
    mode : 文件或目录的权位标志,采用数值格局表示;
    nlink : 文件或目录的的硬连接数量;
    uid : 文件或目录的主人的用户ID。该属性值在UNIX系统下有效;
    gid : 文件或目录的全数者的用户组ID。该属性值在UNIX系统下有效;
    rdev :
    字符设备文件或块设备文件所在设备ID。该属性值在UNIX系统下有效;**
    ino : 文件或目录的索引编号。该属性值仅在UNIX系统下有效;
    size : 文件的字节数;
    * callback(error,stats): error:再次来到的错误新闻
    * stats:重临的打响音讯
    */
    fs.stat(fileaddr,function(error,stats){
    if(error){
    console.log(error)
    }else{
    console.log(stats);
    console.log(stats.isFile());
    console.log(stats.isDirectory());
    console.log(stats.isCharacterDevice());
    console.log(stats.isSymbolicLink());
    console.log(stats.isFIFO());
    console.log(stats.isSocket());
    console.log(stats.isBlockDevice());
    }
    })
    atime : 文件或目录的拜访时间;
    mtime : 文件或目录的末梢修改时间;
    ctime : 文件或目录状态的最终修改时间;
    birthtime : 文件创制时间,文件成立时生成。在某个不提供文件
    birthtime 的文件系统中,这么些字段会动用 ctime 或 一九七零-0一-01T00:00Z
    来填充;
  12. 剔除文件 fs.unlink(path, callback)
    参数表明
    path – 文件路径 callback – 回调函数,无参
    fs.unlink(“test/a.txt”,function(){})

url

┌─────────────────────────────────────────────────────────────────────────────────────────────┐
│                                            href                                             │
├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤
│ protocol │  │        auth         │        host         │           path            │ hash  │
│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │
│          │  │                     │   hostname   │ port │ pathname │     search     │       │
│          │  │                     │              │      │          ├─┬──────────────┤       │
│          │  │                     │              │      │          │ │    query     │       │
"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash "
│          │  │          │          │   hostname   │ port │          │                │       │
│          │  │          │          ├──────────────┴──────┤          │                │       │
│ protocol │  │ username │ password │        host         │          │                │       │
├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │
│   origin    │                     │       origin        │ pathname │     search     │ hash  │
├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤
│                                            href                                             │
└─────────────────────────────────────────────────────────────────────────────────────────────┘

 

http服务器端 :http.server的轩然大波
1、http.Server 的事件
http.Server 是3个基于事件的 HTTP
服务器,全部的央浼都被包裹为单独的事件,开发者只必要对它的风浪编写
响应函数即可完结 HTTP
服务器的享有功效。它连续自伊夫ntEmitter,提供了以下几个事件。
壹request:当客户端请求到来时,该事件被触发,提供三个参数 req
和res,分别是http.ServerRequest 和
http.ServerResponse 的实例,表示请求和响应音信。
request.post(”, {form:{key:’value’}})
request.post(‘)
var r = request.post(”)
var form = r.form()
form.append(‘my_field’, ‘my_value’)
form.append(‘my_buffer’, new Buffer([1, 2, 3]))
form.append(‘my_file’, fs.createReadStream(path.join(__dirname,
‘doodle.png’))
form.append(‘remote_file’, request(”))
var server =new http.Server();
server.on(“request”,function(request,response){
//用于收纳客户端post过来的数据
var reqJson=””;
request.on(“data”,function(chunk){
reqJson +=chunk;
});
request.on(“end”,function(){
console.log(reqJson);
response.writeHead(200,{
‘Content-Type’:’text/html’
});
//对收取的数目处理后再次回到
response.end(reqJson);
})
});
2 connection:当 TCP 连接建霎时,该事件被触发,提供多个参数
socket,为net.Socket 的实例。
connection 事件的粒度要超越 request,因为客户端在Keep-Alive
格局下只怕会在同1个连连内发送多次请
求。
叁close
:当服务器关闭时,该事件被触发。注意不是在用户连接断开时。除此而外还有
checkContinue、
upgrade、clientError 事件,经常我们不须要关爱,唯有在促成复杂的 HTTP
服务器的时候才会用到。
在那么些事件中, 最常用的就是 request 了, 由此 http 提供了3个走后门:
http.createServer([requestListener]) , 功用是创办一个 HTTP
服务器并将requestListener 作为 request 事
件的监听函数,那也是我们日前例子中动用的章程。
var http = require(‘http’);
/**
* 创设服务器的两种写法,第叁种写法如下
*
由于server已经接轨了伊夫ntEmitter的风云功用,所以能够运用高级函数编写情势监察和控制事件
* @param {Function} request event
*/
var server = http.createServer(function(req,res)
{
//这里的req为http.serverRequest
res.writeHeader(200,{‘Content-Type’:’text/plain’});
res.end(‘hello world’);
});
/**
* 表明:创克制务器的第三种写法
* 有关server对象的风浪监听
* @param {Object} req
是http.IncomingMessag的三个实例,在keep-alive连接中协理多少个请求
* @param {Object} res 是http.ServerResponse的贰个实例
*/
var server = new http.Server();
server.on(‘request’,function(req,res){
res.writeHeader(200,{‘Content-Type’:’text/plain’});
res.end(‘hello world’);
});
/**
* 表明:新的TCP流建马上出发。 socket是三个net.Socket对象。
日常用户无需处理该事件。
*
尤其注意,协议解析器绑定套接字时接纳的不贰法门使套接字不会出发readable事件。
还是可以通过
request.connection访问socket。
* @param {Object} socket
*/
server.on(‘connection’,function(socket){});
/**
* 源API: Event: ‘close’
* 表明:关闭服务器时触发
*/
server.on(‘close’,function(){});
/**
* 表明:每当收到Expect: 十0-continue的http请求时接触。
假诺未监听该事件,服务器会研讨自动发送⑩0
Continue响应。
*
处理该事件时,假如客户端能够继承发送请求主体则调用response.writeContinue,
若是不可能则转移合适的HTTP
一呼百应(例如,400 请求无效)
* 须要注意到, 当那个事件触发并且被处理后, request 事件将不再会触发.
* @param {Object} req
* @param {Object} req
*/
server.on(‘checkContinue’,function(req,res){});
/**
*
表达:若是客户端发起connect请求,尽管服务器端未有监听,那么于客户端请求的该连接将会被关闭
* @param {Object} req 是该HTTP请求的参数,与request事件中的相同。
* @param {Object} socket
是服务端与客户端之间的互联网套接字。必要本人写1个data事件监听数据流
* @param {Object} head
是2个Buffer实例,隧道流的首先个包,该参数可能为空。
*/
server.on(‘connect’,function(req,socket,head){});
/**
*
表达:那些事件首如果对HTTP协议升级为其余协商后的风浪监听,倘使服务器端未有监听,那么于客户端请求的该连
接将会被关门
* @param {Object} req 是该HTTP请求的参数,与request事件中的相同。
* @param {Object} socket
是服务端与客户端之间的网络套接字。需求本身写1个data事件监听数据流
* @param {Object} head
是3个Buffer实例,升级后流的首先个包,该参数或者为空。
*/
server.on(‘upgrade’,function(req,socket,head){});
/**
* 表达:假如2个客户端连接触发了1个 ‘error’ 事件, 它就会转接到此处
* @param {Object} exception
* @param {Object} socket
*/
server.on(‘clientError’,function(exception,socket){});
/**
* 源API:server.listen(port, [hostname], [backlog], [callback])
* 表达:监听3个 unix socket,
必要提供多少个文书名而不是端口号和主机名。
* @param {Number} port 端口
* @param {String} host 主机
* @param {Number} backlog
等待队列的最大尺寸,决定于操作系统平台,私下认可是51一
* @param {Function} callback 异步回调函数
*/
//server.listen(3000,’localhost’,100,function(){});
/**
* 源API:server.listen(path, [callback])
* 表达:运转多少个 UNIX 套接字服务器在所给路径 path 上监听连接。
* 恐怕用处:多路径或渠道数据来源监听分隔
* @param {String} path
* @param {Function} callback
*/
//server.listen(‘path’,function(){})
/**
* 源API:server.listen(handle, [callback])
* 表达:Windows 不支持监听叁个文件讲述符。
* @param {Object} handle 变量能够被安装为server 或许 socket
* @param {Function} callback
*/
//server.listen({},function(){});
/**
* 表明:最大请求头数目限制, 私下认可 一千 个. 借使设置为0,
则代表不做其余限制.
* @type {number}
*/
server.maxHeadersCount = 1000;
/**
* 源API:server.setTimeout(msecs, callback)
*
表明:为套接字设定超时值。倘若一个逾期发生,那么Server对象上会分发贰个’timeout’事件,同时将套接字作为
参数字传送递。
* 设置为0将阻止之后建立的接连的方方面面活动超时行为
* @param {Number} msecs
* @param
*/
server.setTimeout(1000,function(){});
/**
* 表明:二个套接字被判定为超时在此以前的闲置飞秒数。 私下认可 1两千0 (二 分钟)
* @type {number}
*/
server.timeout = 120000;
/**
* 表达:那里的主机将是本土
* @param {Number} port 端口
* @param {Function} callback 异步回调函数
*/
server.listen(3000,function(){
console.log(‘Listen port 3000’);
});
var https = require(‘https’);
var zlib = require(‘zlib’);
var post_data=”………………”;//请求数据
var reqdata = JSON.stringify(post_data);
var options = {
hostname: ‘10.225.***.***’,
port: ‘8443’,
path: ‘/data/table/list’,
method: ‘POST’,
rejectUnauthorized: false,
requestCert: true,
nodejs 简单http 文件上传
auth: ‘admin:123456************’,
headers: {
‘username’: ‘admin’,
‘password’: ‘123456************’,
‘Cookie’: ‘locale=zh_CN’,
‘X-BuildTime’: ‘2015-01-01 20:04:11’,
‘Autologin’: ‘4’,
‘Accept-Encoding’: ‘gzip, deflate’,
‘X-Timeout’: ‘3600000’,
‘Content-Type’: ‘Application/json’,
“Content-Length”:reqdata.length
}
};
var req = https.request(options, function (res) {
});
req.write(reqdata);
req.on(‘response’, function (response) {
switch (response.headers[‘content-encoding’]) {
case ‘gzip’:
var body = ”;
var gunzip = zlib.createGunzip();
response.pipe(gunzip);
gunzip.on(‘data’, function (data) {
body += data;
});
gunzip.on(‘end’, function () {
var returndatatojson= JSON.parse(body);
req.end();
});
gunzip.on(‘error’, function (e) {
console.log(‘error’ + e.toString());
req.end();
});
break;
case ‘deflate’:
var output = fs.createWriteStream(“d:temp.txt”);
response.pipe(zlib.createInflate()).pipe(output);
req.end();
break;
default:req.end();
break;
}
});
req.on(‘error’, function (e) {
console.log(new Error(‘problem with request: ‘ + e.message));
req.end();
setTimeout(cb, 10);
});
// 那是2个粗略的Node HTTP,能处理当前目录的文件
// 并能完成良种特殊的U景逸SUVL用于测试
// 用 或 连接这一个服务器
// 首先,加载全数要用的模块
var http = require(‘http’); // HTTP服务器API
var fs = require(‘fs’); // 文件系统API
var server = new http.Server(); // 创立新的HTTP服务器
var port = 8000;
server.listen(port); // 在端口七千伤运维它
var log = require(‘util’).log;
log(‘Http Server is listening ‘ + port + ‘ port.’);
// Node使用’on’方法注册事件处理程序
// 当服务器收到新请求,则运维函数处理它
server.on(‘request’, function(request, response) {
var filename = null;
// 解析呼吁的UOdysseyL
var url = require(‘url’).parse(request.url);
switch(url.pathname) {
case ‘/upload’:
var _fileName = request.headers[‘file-name’];
log(_fileName);
request.once(‘data’, function(data) {
// 大文件
// var fis = fs.createWriteStream(‘/txt.txt’);
// fis.write(data);
// fis.end();
fs.writeFile(_fileName, data);
response.end();
});
break;
case ‘/’ || ‘/index.html’ :
filename = ‘index.html’;
default:
filename = filename || url.pathname.substring(一); // 去掉前导’/’
// 基于其扩充名猜度内容类型
var type = (function(_type) {
switch(_type) { // 扩展名
case ‘html’:
case ‘htm’: return ‘text/html; charset=UTF-8’;
case ‘js’: return ‘application/javascript; charset=UTF-8’;
case ‘css’: return ‘text/css; charset=UTF-8’;
case ‘txt’: return ‘text/plain; charset=UTF-8’;
case ‘manifest’: return ‘text/cache-manifest; charset=UTF-8’;
default: return ‘application/octet-stream’;
}
}(filename.substring(filename.lastIndexOf(‘.’) + 1)));
// 异步读取文件,并将内容作为单身的数码块传回给回调函数
// 对于确实极大的文本,使用API fs.createReadStream()更加好
fs.readFile(filename, function(err, content) {
if (err) { // 假如由于某个原因无法读取文件
response.writeHead(404, {‘Content-type’ : ‘text/plain;
charset=UTF-8’});
response.write(err.message);

} else { // 不然读取文件成功
response.writeHead(200, {‘Content-type’ : type});
response.write(content); // 把文件内容作为响应宗旨
}
response.end();
});
}
});

2、http.ServerRequest
http.ServerRequest 是 HTTP
请求的消息,是后端开发者最关心的情节。它1般由http.Server 的 request
事件发送,作为第三个参数字传送递,通常简称 request 或 req。
HTTP 请求一般能够分为两有个别:请求头(Request Header)和请求体(Requset
Body)。以上内容由于长
度较短都可以在请求头解析完成后迅即读取。而请求体只怕相对较长,须求一定的岁月传输。
http.ServerRequest 提供了以下一个事件用于控制请求体传输。
data :当请求体数据来权且,该事件被触发。该事件提供一个参数
chunk,表示收到到的多少。假设该事件
一贯不被监听,那么请求体将会被甩掉。该事件或然会被调用数13遍。
end :当请求体数据传输实现时,该事件被触发,此后将不会再有数量来临。
close: 用户眼下恳请甘休时,该事件被触发。分歧于
end,若是用户强制停止了传输,也依旧调用close。

 

 

 

code=`

在后面包车型客车有着章节中,大家编辑的JavaScript代码都是在浏览器中运维的,因而,大家得以平昔在浏览器中敲代码,然后径直运营。

(function($require,module,exports,__dirname,__filename){

从本章发轫,我们编辑的JavaScript代码将不能在浏览器环境中履行了,而是在Node环境中执行,由此,JavaScript代码将一直在你的微处理器上以命令行的法子运营,所以,大家要先选择三个文件编辑器来编排JavaScript代码,并且把它保存到本地硬盘的某部目录,才能够实践。

 ${code}

那么难点来了:文本编辑器到底哪家强?

})($require,module,exports,dirname,filename)

引入三款文本编辑器:

;`;

一个是Sublime
Text,免费使用,但是不付钱会弹出提醒框:

eval(code);

hello.js

 

一个是Notepad++,免费应用,有汉语界面:

$require.cache[filename] = module;

notepad-hello.js

return module.exports;

请小心,用哪些都行,不过相对无法用Word和写字板,Windows自带的记事本也人所共知不引入应用。Word和写字板保存的不是纯文本文件,而记事本会班门弄斧地在文件伊始的地方加上多少个特殊字符(UTF-八BOM),结果常常会促成程序运维出现无缘无故的荒谬。

}

设置好文件编辑器后,输入以下代码:

 

‘use strict’;console.log(‘Hello, world.’);

var m4 =  $require(‘../xx.js’);

首先行总是写上’use strict’;

m4.say();

是因为我们总是以严俊形式运行JavaScript代码,防止各个神秘陷阱。然后,选拔二个索引,例如C:\Workspace,把公文物保护留为hello.js,就足以打开命令行窗口,把当前目录切换成hello.js所在目录,然后输入以下命令运转这么些顺序了:

C:\Workspace>node hello.js

 

Hello, world.

清空require中的缓存机制:

也得以保存为别的名字,比如first.js,不过必须求以.js结尾。此外,文件名只可以是英文字母、数字和下划线的结合。

Object.keys(require.cache).forEach((key)=>{delete
require.cache[key]});

借使当前目录下并未有hello.js那一个文件,运转node hello.js就会报错:

 

C:\Workspace>node hello.jsmodule.js:338 throw err; ^Error: Cannot
find module ‘C:\Workspace\hello.js’ at
Function.Module._resolveFilename at Function.Module._load at
Function.Module.runMain at startup at node.js

嵌入模块:

报错的趣味正是,未有找到hello.js那些文件,因为文件不设有。这一年,就要检查一下当前目录下是还是不是有这几个文件了。

path:处理公事路径。

命令行格局和Node交互情势

fs:操作(CRUD)文件系统。

请注意区分命令行情势和Node交互格局。看到类似C:\>是在Windows提供的命令行形式:

child_process:新建子线程。

run-node-hello

util:提供一多元实用小工具。

在命令行情势下,能够执行node进入Node交互式环境,也足以实施nodehello.js运维3个.js文件。看到>是在Node交互式环境下:

http:提供http服务器功效。

node-interactive-env

url:用于解析UCRUISERL。

在Node交互式环境下,我们得以输入JavaScript代码并当即实施。此外,在命令行格局运维.js文件和在Node交互式环境下直接运营JavaScript代码有所差别。Node交互式环境会把每一行JavaScript代码的结果自动打字与印刷出来,不过,间接运营JavaScript文件却不会。

querystring:解析ULANDL中的查询字符串。

例如,在Node交互式环境下,输入:

crypto:提供加密和解密作用。

> 100 + 200 + 300;

.. 

600

包(Node package manager):

平素能够看来结果600。

 

而是,写3个calc.js的文书,内容如下:

 

100 + 200 + 300;

 

下一场在命令行情势下进行:

Buffer

C:\Workspace>node calc.js

:读取文件时从没点名编码默许读取的是一个Buffer(缓冲区)

发觉怎么输出都不曾。那是常规的。想要输出结果,必须自身用console.log()打印出来。把calc.js改造一下:

缓冲区:内部存款和储蓄器中操作数据的器皿。

console.log(100+200+300);

 

再进行,就能够见到结果:

为何要有缓冲区?

C:\Workspace>node calc.js

初期JS擅长处理字符串,及HTML文书档案,不会触发到2进制的数量。

600

而在Node中操作数据,网络通讯是一点一滴没办法以字符串的章程操作的,所以在Node中引进了多少个二进制缓冲区的落到实处,Buffer

用文件编辑器写JavaScript程序,然后保留为后缀为.js的公文,就足以用node直接运维那么些程序了。

//readfile的点子的确是接纳buffer,不过也是一次性读取

Node的相互方式和一贯运营.js文件有怎样界别吧?

 

直白输入node进入相互方式,相当于运营了Node解释器,不过等待你一行一行地输入源代码,每输入1行就实施一行。

Stream:

直白运转node
hello.js文件也等于运营了Node解释器,然后叁次性把hello.js文件的源代码给执行了,你是尚未机会以互相的措施输入源代码的。

读一些多少,处理一小点数据(读到有限长的buffer中,然后再读取出来,)

在编写制定JavaScript代码的时候,完全能够一边在文件编辑器里写代码,一边开3个Node交互式命令窗口,在写代码的历程中,把部分代码粘到命令行去验证,一举两得!前提是得有个2七’的重特大显示器!

 

模块

写一个歌词滚动作效果应的兑现:

在计算机程序的付出进度中,随着程序代码越写更加多,在2个文件里代码就会更为长,越来越不不难保证。

尽管有三个xxx.lrc文件

为了编制可保险的代码,大家把过多函数分组,分别放置分裂的文本里,那样,每一个文件包括的代码就相对较少,很多编制程序语言都利用这种组织代码的章程。在Node环境中,2个.js文件就叫做八个模块(module)。

 

使用模块有哪些利益?

措施一.用buffer的法子读入fs.readFile(pathxx,callback)

最大的功利是大大升高了代码的可维护性。其次,编写代码不必从零初始。当一个模块编写达成,就足以被其余省方引用。大家在编写程序的时候,也常常引用其余模块,包罗Node内置的模块和来自第二方的模块。

在回调函数中对buffer进行tostring转换,然后split掉’\n’,对于数组中的每壹行,用正则提取时间,然后settimeout按时间呈现出来

动用模块还足以制止函数名和变量名冲突。相同名字的函数和变量完全能够分别设有区别的模块中,因而,大家团结在编写制定模块时,不必思量名字会与任何模块冲突。

(由于对每一行处理须求消耗几飞秒的大运,可以安装begin=new
Date().getTime() 然后在末端的settimeout中安装新的new
Date.getTime()-begin 减掉那个时刻)

在上一节,我们编辑了叁个hello.js文件,这几个hello.js文件正是多少个模块,模块的名字正是文本名(去掉.js后缀),所以hello.js文件就是名称为hello的模块。

办法二.用stream的艺术读入 var streamReader =
fs.createReadStream(filename);

作者们把hello.js改造一下,创造1个函数,这样大家就足以在任哪里方调用这一个函数:

var data = ”;

‘use strict’;vars =’Hello’;functiongreet(name){console.log(s +’, ‘+ name
+’!’);}module.exports = greet;

streamReader.on(‘data’,function(chunk){  data+=chunk.tostring(); });

函数greet()是我们在hello模块中定义的,你或然注意到最终一行是三个想不到的赋值语句,它的情致是,把函数greet作为模块的出口暴流露来,那样任何模块就能够使用greet函数了。

streamReader.on(‘end’,function(){console.log(data);  };  

难点是其它模块怎么使用hello模块的这一个greet函数呢?我们再编辑1个main.js文件,调用hello模块的greet函数:

在那里对data举办拍卖

‘use strict’;// 引入hello模块:vargreet =require(‘./hello’);vars
=’Michael’;greet(s);// Hello, Michael!

形式3.行使readline模块,用stream的不二等秘书诀读入 var streamReader =
fs.createReadStream(filename);  

瞩目到引进hello模块用Node提供的require函数:

var rl = readline.createInterface({ input:streamReader });

vargreet =require(‘./hello’);

var begin = new Date().getTime();

引进的模块作为变量保存在greet变量中,那greet变量到底是何许事物?其实变量greet正是在hello.js中大家用module.exports

greet;输出的greet函数。所以,main.js就成功地引用了hello.js模块中定义的greet()函数,接下去就能够间接选用它了。

在利用require()引进模块的时候,请留心模块的相对路径。因为main.js

和hello.js位于同1个索引,所以我们用了脚下目录.:

vargreet =require(‘./hello’);// 不要忘了写绝对目录!

万二只写模块名:

vargreet =require(‘hello’);

则Node会依次在松开模块、全局模块和当前模块下寻找hello.js,你很恐怕会取得二个不当:

module.js throw err; ^Error: Cannot find module ‘hello’ at

Function.Module._resolveFilename at Function.Module._load … at

Function.Module._load at Function.Module.runMain

遇见那一个错误,你要反省:

模块名是或不是写对了

模块文件是还是不是留存

相对路径是还是不是写对了

CommonJS规范

那种模块加运载飞机制被称作CommonJS规范。在这么些正式下,每一个.js文件都是三个模块,它们之中各自行使的变量名和函数名都互不争执,例如,hello.js

和main.js都申明了全局变量var s = ‘xxx’,但互不影响。

三个模块想要对外暴光变量(函数也是变量),能够用module.exports =
variable;,叁个模块要引用别的模块揭示的变量,用

varref =require(‘module_name’);

就获得了引用模块的变量。

要在模块中对外出口变量,用:module.exports = variable;

输出的变量能够是轻易对象、函数、数组等等。要引进其余模块输出的靶子,用:var
foo = require(‘other_module’);

引进的靶子实际是什么样,取决于引进模块输出的对象。

深刻掌握模块原理

借使你想详细地打听CommonJS的模块达成原理,请继续往下阅读

当大家编辑JavaScript代码时,大家能够评释全局变量:

vars =’global’;

在浏览器中,多量采纳全局变量可不好。若是你在a.js中应用了大局变量s,那么,在b.js中也应用全局变量s,将促成争论,b.js中对s赋值会转移a.js的周转逻辑。

也正是说,JavaScript语言自身并未壹种模块机制来担保不一致模块能够采用同样的变量名。

这Node.js是何许兑现那一点的?

骨子里要兑现“模块”那几个效果,并不须求语法层面包车型地铁补助。Node.js也并不会增多别的JavaScript语法。达成“模块”功效的微妙就在于JavaScript是一种函数式编制程序语言,它支持闭包。假诺我们把壹段JavaScript代码用3个函数包装起来,那段代码的有所“全局”变量就变成了函数内部的一部分变量。

请留意咱们编辑的hello.js代码是这么的:

vars =’Hello’;varname =’world’;console.log(s +’ ‘+ name +’!’);

Node.js加载了hello.js后,它能够把代码包装一下,变成那样实行:

(function(){// 读取的hello.js代码:vars =’Hello’;varname
=’world’;console.log(s +’ ‘+ name +’!’);// hello.js代码截止})();

那样1来,原来的全局变量s未来成为了匿名函数内部的有的变量。倘诺Node.js继续加载其余模块,那个模块中定义的“全局”变量s也互不烦扰。

从而,Node利用JavaScript的函数式编制程序的特征,举手之劳地达成了模块的隔绝。

不过,模块的出口module.exports怎么落实?

其①也很简单达成,Node能够先准备一个对象module:

// 准备module对象:varmodule= {id:’hello’,exports: {}};varload
=function(module){//
读取的hello.js代码:functiongreet(name){console.log(‘Hello, ‘+ name
+’!’);  }module.exports = greet;//
hello.js代码甘休returnmodule.exports;};varexported = load(module);//
保存module:save(module, exported);

足见,变量module是Node在加载js文件前准备的2个变量,并将其扩散加载函数,大家在hello.js中能够直接采纳变量module原因就在于它实际上是函数的二个参数:module.exports
= greet;

经过把参数module传递给load()函数,hello.js就万事大吉地把多个变量传递给了Node执行环境,Node会把module变量保存到有些地方。

是因为Node保存了装有导入的module,当我们用require()获取module时,Node找到相应的module,把那一个module的exports变量返回,那样,另三个模块就万事大吉获得了模块的出口:

vargreet =require(‘./hello’);

如上是Node完成JavaScript模块的二个不难的原理介绍。

module.exports vs exports

众多时候,你会师到,在Node环境中,有两种艺术能够在1个模块中输出变量:

方法一:对module.exports赋值:

// hello.jsfunctionhello(){console.log(‘Hello,
world!’);}functiongreet(name){console.log(‘Hello, ‘+ name
+’!’);}functionhello(){console.log(‘Hello, world!’);}module.exports =
{hello: hello,greet: greet};

措施贰:直接使用exports:

// hello.jsfunctionhello(){console.log(‘Hello,
world!’);}functiongreet(name){console.log(‘Hello, ‘+ name
+’!’);}functionhello(){console.log(‘Hello, world!’);}exports.hello =
hello;exports.greet = greet;

可是你不得以平素对exports赋值:

// 代码能够执行,但是模块并未有出口任何变量:exports = {hello:
hello,greet: greet};

假设你对地方的写法感到万分疑心,不要心急,大家来分析Node的加载机制:

先是,Node会把全路待加载的hello.js文件放入1个包裹函数load中推行。在推行这几个load()函数前,Node准备好了module变量:

varmodule= {id:’hello’,exports: {}};

load()函数最后回到module.exports:

varload =function(exports, module){// hello.js的公文内容 …//
load函数再次回到:returnmodule.exports;};varexported =
load(module.exports,module);

也正是说,暗中认可景况下,Node准备的exports变量和module.exports变量实际上是同贰个变量,并且开端化为空对象{},于是,大家得以写:

exports.foo =function(){return’foo’; };exports.bar
=function(){return’bar’; };

也足以写:

module.exports.foo =function(){return’foo’; };module.exports.bar
=function(){return’bar’; };

换句话说,Node默许给您准备了1个空对象{},那样你可以一贯往里面加东西。

然而,假若大家要出口的是叁个函数或数组,那么,只好给module.exports

赋值:

module.exports =function(){return’foo’; };

给exports赋值是对事情未有什么帮助的,因为赋值后,module.exports依然是空对象{}。

结论:

假如要出口2个键值对象{},能够使用exports这些已存在的空对象{},并卫冕在上边添加新的键值;

假若要出口一个函数或数组,必须一向对module.exports对象赋值。

因而大家得以得出结论:直接对module.exports赋值,能够回答其余景况:

module.exports = {foo:function(){return’foo’;  }};

或者:

module.exports =function(){return’foo’; };

最终,我们强烈提议运用module.exports =
xxx的措施来输出模块变量,那样,你只需求回想一种办法。

着力模块

因为Node.js是运营在服务区端的JavaScript环境,服务器程序和浏览器先后相比,最大的表征是一向不浏览器的安全限制了,而且,服务器程序必须能接收互联网请求,读写文件,处理二进制内容,所以,Node.js内置的常用模块正是为了促成主题的服务器功能。这几个模块在浏览器环境中是不可能被实施的,因为它们的平底代码是用C/C++在Node.js运转条件中达成的。

global

在头里的JavaScript课程中,我们早已掌握,JavaScript有且仅有1个大局对象,在浏览器中,叫window对象。而在Node.js环境中,也有唯一的全局对象,但不叫window,而叫global,这一个指标的个性和艺术也和浏览器环境的window不一致。进入Node.js交互环境,可以一向输入:

> global.console

Console {

log: [Function: bound ],

info: [Function: bound ],

warn: [Function: bound ],

error: [Function: bound ],

dir: [Function: bound ],

time: [Function: bound ],

timeEnd: [Function: bound ],

trace: [Function: bound trace],

assert: [Function: bound ],

Console: [Function: Console] }

process

process也是Node.js提供的三个目的,它表示当前Node.js进程。通过process对象能够获得不少有用消息:

4858美高梅,> process === global.process;

true

> process.version;

‘v5.2.0’

> process.platform;

‘darwin’

> process.arch;

‘x64’

> process.cwd(); //再次来到当前工作目录

‘/Users/michael’

> process.chdir(‘/private/tmp’); // 切换当前工作目录

undefined

> process.cwd();

‘/private/tmp’

JavaScript程序是由事件驱动执行的单线程模型,Node.js也不例外。Node.js不断执行响应事件的JavaScript函数,直到未有此外响应事件的函数能够实施时,Node.js就淡出了。

1旦大家想要在下二遍事件响应中履行代码,能够调用process.nextTick():

// test.js//
process.nextTick()将在下一轮事件循环中调用:process.nextTick(function(){console.log(‘nextTick
callback!’);});console.log(‘nextTick was set!’);

用Node执行上边包车型客车代码node test.js,你会看出,打字与印刷输出是:

nextTick was set!

nextTick callback!

那注脚传入process.nextTick()的函数不是当时实施,而是要等到下三回事件循环。

Node.js进度自身的轩然大波就由process对象来拍卖。假使大家响应exit事件,就足以在先后即将退出时实施有个别回调函数:

//
程序即将退出时的回调函数:process.on(‘exit’,function(code){console.log(‘about
to exit with code: ‘+ code);});

判断JavaScript执行环境

有那一个JavaScript代码既能在浏览器中履行,也能在Node环境执行,但有个别时候,程序自身要求看清自个儿毕竟是在如何环境下实施的,常用的不二法门便是依据浏览器和Node环境提供的全局变量名称来判断:

if(typeof(window) ===’undefined’)
{console.log(‘node.js’);}else{console.log(‘browser’);}

末端,大家将介绍Node.js的常用内置模块。

fs

Node.js内置的fs模块就是文件系统模块,负责读写文件。

和有着其余JavaScript模块差异的是,fs模块同时提供了异步和壹块的不2秘籍。

追忆一下什么样是异步方法。因为JavaScript的单线程模型,执行IO操作时,JavaScript代码无需等待,而是传入回调函数后,继续执行后续JavaScript代码。比如jQuery提供的getJSON()操作:

$.getJSON(‘…’);

而同步的IO操作则供给静观其变函数重临:

// 依照互连网耗费时间,函数将执行几拾阿秒~几秒不等:vardata =
getJSONSync(”);

同步操作的功利是代码不难,缺点是先后将等待IO操作,在等候时间内,不恐怕响应别的任何事件。而异步读取不用等待IO操作,但代码较艰辛。

异步读文件

依照JavaScript的正式,异步读取三个文书文件的代码如下:

‘use strict’;varfs
=require(‘fs’);fs.readFile(‘sample.txt’,’utf-8′,function(err,
data){if(err) {console.log(err);  }else{console.log(data);  }});

请小心,sample.txt文件必须在当前目录下,且文件编码为utf-8。

异步读取时,传入的回调函数接收七个参数,当符合规律读取时,err参数为null,data参数为读取到的String。当读取发生错误时,err参数代表三个谬误对象,data为undefined。

那也是Node.js标准的回调函数:第1个参数代表错误新闻,第3个参数代表结果。前面大家还会时不时编写那种回调函数。

是因为err是不是为null即是判断是或不是出错的申明,所以经常的判断逻辑总是:

if(err) {// 出错了}else{// 正常}

假若大家要读取的文书不是文件文件,而是2进制文件,怎么做?

上边包车型客车例子演示了哪些读取3个图纸文件:

‘use strict’;varfs =require(‘fs’);fs.readFile(‘sample.png’,function(err,
data){if(err) {console.log(err); 
}else{console.log(data);console.log(data.length +’ bytes’);  }});

当读取2进制文件时,不扩随笔件编码时,回调函数的data参数将重回1个Buffer对象。在Node.js中,Buffer对象正是三个包罗零个或自由个字节的数组(注意和Array不一致)。

Buffer对象足以和String作转换,例如,把三个Buffer对象转换来String:

// Buffer -> Stringvartext =
data.toString(‘utf-8’);console.log(text);

照旧把三个String转换到Buffer:

// String -> Buffervarbuf =newBuffer(text,’utf-8′);console.log(buf);

协助实行读文件

除了正规的异步读取情势外,fs也提供对应的同台读取函数。同步读取的函数和异步函数比较,多了三个Sync后缀,并且不收受回调函数,函数直接回到结果。

用fs模块同步读取1个文件文件的代码如下:

‘use strict’;varfs =require(‘fs’);vardata =
fs.readFileSync(‘sample.txt’,’utf-8′);console.log(data);

可知,原异步调用的回调函数的data被函数直接回到,函数名急需改为readFileSync,此外参数不变。

若是同步读取文件发出错误,则需求用try…catch捕获该错误:

try{vardata =
fs.readFileSync(‘sample.txt’,’utf-8′);console.log(data);}catch(err) {//
出错了}

写文件

将数据写入文件是透过fs.writeFile()达成的:

‘use strict’;varfs =require(‘fs’);vardata =’Hello,
Node.js’;fs.writeFile(‘output.txt’, data,function(err){if(err)
{console.log(err);  }else{console.log(‘ok.’);  }});

writeFile()的参数依次为文件名、数据和回调函数。假设传入的数量是String,私下认可按UTF-八编码写入文本文件,若是传入的参数是Buffer,则写入的是二进制文件。回调函数由于只关心成功与否,由此只需求二个err参数。

和readFile()类似,writeFile()也有3个联合署名方法,叫writeFileSync():

‘use strict’;varfs =require(‘fs’);vardata =’Hello,
Node.js’;fs.writeFileSync(‘output.txt’, data);

stat

只要大家要赢得文件大小,创设时间等音信,可以利用fs.stat(),它回到三个Stat对象,能告诉大家文件或目录的详细新闻:

‘use strict’;varfs =require(‘fs’);fs.stat(‘sample.txt’,function(err,
stat){if(err) {console.log(err);  }else{//
是否是文件:console.log(‘isFile: ‘+ stat.isFile());//
是还是不是是目录:console.log(‘isDirectory: ‘+
stat.isDirectory());if(stat.isFile()) {// 文件大小:console.log(‘size: ‘+
stat.size);// 创立时间, Date对象:console.log(‘birth time: ‘+
stat.birthtime);// 修改时间, Date对象:console.log(‘modified time: ‘+
stat.mtime);    }  }});

运转结果如下:

isFile: true

isDirectory: false

size: 181

birth time: Fri Dec 11 2015 09:43:41 GMT+0800 (CST)

modified time: Fri Dec 11 2015 12:09:00 GMT+0800 (CST)

stat()也有一个对应的一起函数statSync(),请试着改写上述异步代码为共同代码。

异步依然一块

在fs模块中,提供联合方法是为了方便使用。那大家到底是应该用异步方法也许1道方法吗?

鉴于Node环境执行的JavaScript代码是劳动器端代码,所以,绝超越三分之壹亟待在服务器运维期反复实践工作逻辑的代码,总得运用异步代码,不然,同步代码在实施时代,服务器将终止响应,因为JavaScript唯有一个实践线程。

服务器运营时假诺急需读取配置文件,或许终止时需求写入到状态文件时,能够接纳同步代码,因为这一个代码只在开行和结束时进行1回,不影响服务器常规运转时的异步执行。

stream

stream是Node.js提供的又二个仅在劳务区端可用的模块,目的是协理“流”这种数据结构。

如何是流?流是1种浮泛的数据结构。想象水流,当在水管中流淌时,就能够从某些地方(例如自来水厂)继续不停地抵达另三个地方(比如你家的洗手池)。

大家也能够把数量作为是数据流,比如你敲键盘的时候,就足以把每一个字符依次连起来,看成字符流。那一个流是从键盘输入到应用程序,实际上它还对应着一个名字:标准输入流(stdin)。

借使应用程序把字符1个一个输出到显示屏上,那也得以看做是一个流,这一个流也知名字:标准输出流(stdout)。流的特征是数据是平稳的,而且必须逐项读取,只怕依次写入,不能像Array这样随机定位。

4858美高梅 3

nodejs-stream

有点流用来读取数据,比如从文件读取数据时,可以打开一个文书流,然后从文件流中不断地读取数据。有个别流用来写入数据,比如向文件写入数据时,只供给把多少持续地往文件流中写进去就足以了。

在Node.js中,流也是3个目的,大家只须要响应流的风云就能够了:data事件代表流的数额现已足以读取了,end事件表示这些流已经到结尾了,未有多少年足球以读取了,error事件代表出错了。

下边是三个从文件流读取文本内容的示范:

‘use strict’;varfs =require(‘fs’);// 打开2个流:varrs =
fs.createReadStream(‘sample.txt’,’utf-八’);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(‘E奥德赛RO凯雷德:
‘+ err);});

要留心,data事件大概会有反复,每一趟传递的chunk是流的一部分数据。

要以流的款式写入文件,只需求不停调用write()方法,最终以end()甘休:

‘use strict’;varfs =require(‘fs’);varws1 =

rl.on(‘line’,(line)=>{….对line举办拍卖})

fs.createWriteStream(‘output壹.txt’,’utf-8′);ws1.write(‘使用Stream写入文本数据…\n’);ws1.write(‘END.’);ws1.end();varws2

fs.createWriteStream(‘output2.txt’);ws二.write(newBuffer(‘使用Stream写入贰进制数据…\n’,’utf-8′));ws2.write(newBuffer(‘END.’,’utf-8′));ws2.end();

持有能够读取数据的流都继承自stream.Readable,全部能够写入的流都继承自stream.Writable。

pipe

如同能够把五个水管串成三个越来越长的水管1样,八个流也足以串起来。贰个Readable流和三个Writable流串起来后,全部的多少自动从Readable

流进去Writable流,那种操作叫pipe。

在Node.js中,Readable流有三个pipe()方法,正是用来干那件事的。

让大家用pipe()把二个文件流和另2个文书流串起来,那样源文件的富有数据就机关写入到对象文件里了,所以,那实在是三个复制文件的次第:

‘use strict’;varfs =require(‘fs’);varrs =
fs.createReadStream(‘sample.txt’);varws =
fs.createWriteStream(‘copied.txt’);rs.pipe(ws);

私下认可景况下,当Readable流的数据读取完毕,end事件触发后,将电动关闭Writable流。假使大家不指望电动关闭Writable流,必要传入参数:

readable.pipe(writable, {end:false});

http

Node.js开发的目标就是为着用JavaScript编写Web服务器程序。因为JavaScript实际晚春经执政了浏览器端的本子,其优势正是有世界上多少最多的前端开发职员。借使已经通晓了JavaScript前端开发,再念书一下怎样将JavaScript应用在后端开发,正是名副其实的全栈了。

HTTP协议

要了解Web服务器程序的行事原理,首先,大家要对HTTP协议有中央的摸底。借使你对HTTP协议不太理解,先看一看HTTP协议简介。

HTTP服务器

要成本HTTP服务器程序,从头处理TCP连接,解析HTTP是不具体的。这个干活儿实际桃浪经由Node.js自带的http模块形成了。应用程序并不直接和HTTP协议打交道,而是操作http模块提供的request和response对象。

request对象封装了HTTP请求,我们调用request对象的天性和方法就能够获得拥有HTTP请求的新闻;

response对象封装了HTTP响应,我们操作response对象的情势,就可以把HTTP响应重回给浏览器。

用Node.js完成二个HTTP服务器程序非常简单。我们来落成3个最简单易行的Web程序hello.js,它对于持有请求,都回去Hello
world!:

‘use strict’;// 导入http模块:varhttp =require(‘http’);// 创立http
server,并传播回调函数:varserver = http.createServer(function(request,
response){// 回调函数接收request和response对象,//
获得HTTP请求的method和url:console.log(request.method +’: ‘+
request.url);// 将HTTP响应200写入response, 同时安装Content-Type:
text/html:response.writeHead(200, {‘Content-Type’:’text/html’});//
将HTTP响应的HTML内容写入response:response.end(‘

 

Hello world!

‘);});// 让服务器监听8080端口:server.listen(8080);console.log(‘Server is
running at ‘);

在命令提醒符下运转该程序,能够看来以下输出:

$ node hello.js Server is running at

毫非亲非故闭命令指示符,直接打开浏览器输入

http-hello-sample

与此同时,在命令提醒符窗口,能够看到程序打字与印刷的乞求音讯:

GET: /GET: /favicon.ico

那正是我们编辑的第3个HTTP服务器程序!

文本服务器

让我们一连壮大学一年级下地方的Web程序。大家能够设定一个索引,然后让Web程序变成一个文件服务器。要落到实处那点,大家只要求解析request.url中的路径,然后在本土找到相应的文书,把文件内容发送出去就能够了。

解析U大切诺基L需求动用Node.js提供的url模块,它采纳起来卓殊简单,通过parse()将3个字符串解析为贰个Url对象:

‘use strict’;varurl
=require(‘url’);console.log(url.parse(”));

结果如下:

Url {

protocol: ‘http:’,

slashes: true,

auth: ‘user:pass’,

host: ‘host.com:8080’,

port: ‘8080’,

hostname: ‘host.com’,

hash: ‘#hash’,

search: ‘?query=string’,

query: ‘query=string’,

pathname: ‘/path/to/file’,

path: ‘/path/to/file?query=string’,

href: ”

}

拍卖地点文件目录须要动用Node.js提供的path模块,它能够一本万利地布局目录:

‘use strict’;varpath =require(‘path’);// 解析当前目录:varworkDir =
path.resolve(‘.’);// ‘/Users/michael’//
组合完整的文本路径:当前目录+’pub’+’index.html’:varfilePath =
path.join(workDir,’pub’,’index.html’);// ‘/Users/michael/pub/index.html’

动用path模块能够正确处理操作系统相关的文本路径。在Windows系统下,再次来到的不2诀要类似于C:\Users\michael\static\index.html,那样,我们就不关切怎么拼接路径了。

末尾,大家兑现1个文件服务器file_server.js:

‘use strict’;varfs =require(‘fs’),      url =require(‘url’),      path
=require(‘path’),      http =require(‘http’);//
从命令行参数获取root目录,暗中认可是当前目录:varroot =
path.resolve(process.argv[2] ||’.’);console.log(‘Static root dir: ‘+
root);// 成立服务器:varserver = http.createServer(function(request,
response){// 获得UWranglerL的path,类似 ‘/css/bootstrap.css’:varpathname =
url.parse(request.url).pathname;// 获得相应的地面文件路径,类似
‘/srv/www/css/bootstrap.css’:varfilepath = path.join(root, pathname);//
获取文件状态:fs.stat(filepath,function(err, stats){if(!err &&
stats.isFile()) {// 没有出错并且文件存在:console.log(‘200 ‘+
request.url);// 发送200响应:response.writeHead(200);//
将文件流导向response:fs.createReadStream(filepath).pipe(response);   
}else{// 出错了恐怕文件不存在:console.log(’40四 ‘+ request.url);//
发送404响应:response.writeHead(40四);      response.end(’40四 Not
Found’);    }  });});server.listen(8080);console.log(‘Server is running
at ‘);

从不须要手动读取文件内容。由于response对象自笔者是叁个Writable
Stream,直接用pipe()方法就落实了自动读取文件内容并出口到HTTP响应。

在命令行运维node file_server.js
/path/to/dir,把/path/to/dir改成你本地的多少个管用的目录,然后在浏览器中输入

http-index-page

1经当前目录下存在文件index.html,服务器就足以把公文内容发送给浏览器。观看控制台出口:

200 /index.html

200 /css/uikit.min.css

200 /js/jquery.min.js

200 /fonts/fontawesome-webfont.woff2

率先个请求是浏览器请求index.html页面,后续请求是浏览器解析HTML后发送的其余国资本源请求。

crypto

crypto模块的目的是为了提供通用的加密和哈希算法。用纯JavaScript代码达成这个效应不是不容许,但速度会丰硕慢。Nodejs用C/C++完毕这个算法后,通过cypto那一个模块揭露为JavaScript接口,那样用起来方便,运转速度也快。

MD5和SHA1

MD伍是一种常用的哈希算法,用于给自由数据1个“签名”。那个签名平日用3个十六进制的字符串表示:

constcrypto =require(‘crypto’);consthash = crypto.createHash(‘md5’);//
可任意数十次调用update():hash.update(‘Hello, world!’);hash.update(‘Hello,
nodejs!’);console.log(hash.digest(‘hex’));//
7e1977739c748beac0c0fd14fd26a544

update()方法暗许字符串编码为UTF-8,也足以流传Buffer。

比方要总结SHA一,只须求把’md五’改成’sha一’,就可以取得SHA1的结果

1f32b9c9932c02227819a4151feed43e131aca40

还足以选用更安全的sha25六和sha51二。

Hmac

Hmac算法也是1种哈希算法,它能够选拔MD5或SHA1等哈希算法。差异的是,Hmac还亟需叁个密钥:

constcrypto =require(‘crypto’);consthmac =
crypto.createHmac(‘sha256′,’secret-key’);hmac.update(‘Hello,
world!’);hmac.update(‘Hello,
nodejs!’);console.log(hmac.digest(‘hex’));// 80f7e22570…

要是密钥产生了变通,那么相同的输入数据也会赢得分化的签字,由此,能够把Hmac驾驭为用随机数“增强”的哈希算法。

AES

AES是1种常用的对称加密算法,加解密都用同二个密钥。crypto模块提供了AES援助,不过急需团结包装好函数,便于使用:

constcrypto =require(‘crypto’);functionaesEncrypt(data, key){constcipher
= crypto.createCipher(‘aes192′, key);varcrypted =
cipher.update(data,’utf8′,’hex’);  crypted +=
cipher.final(‘hex’);returncrypted;}functionaesDecrypt(data,
key){constdecipher = crypto.createDecipher(‘aes192′, key);vardecrypted =
decipher.update(encrypted,’hex’,’utf8′);  decrypted +=
decipher.final(‘utf8′);returndecrypted;}vardata =’Hello, this is a
secret message!’;varkey =’Password!’;varencrypted = aesEncrypt(data,
key);vardecrypted = aesDecrypt(encrypted, key);console.log(‘Plain text:
‘+ data);console.log(‘Encrypted text: ‘+
encrypted);console.log(‘Decrypted text: ‘+ decrypted);

运营结果如下:

Plain text: Hello, this is a secret message!

Encrypted text: 8a944d97bdabc157a5b7a40cb180e7…

Decrypted text: Hello, this is a secret message!

可以看出,加密后的字符串通过解密又拿到了原有内容。

瞩目到AES有诸多不相同的算法,如aes192,aes-12八-ecb,aes-25六-cbc等,AES除了密钥外还是可以够内定IV(Initial
Vector),差异的连串壹旦IV分化,用相同的密钥加密相同的数额得到的加密结果也是区别的。

加密结果平日有三种象征方法:hex和base6四,这一个效应Nodejs全部都协助,然则在应用中要留心,假如加解密两方一方用Nodejs,另1方用Java、PHP等任何语言,供给精心测试。倘使不能够正确解密,要肯定互相是还是不是服从千篇一律的AES算法,字符串密钥和IV是还是不是同样,加密后的数码是不是统壹为hex或base6四格式。

Diffie-Hellman

DH算法是1种密钥沟通协议,它能够让两者在不败露风声密钥的情况下协商出多个密钥来。DH算法基于数学原理,比如小明和小红想要协商三个密钥,可以那样做:

小明先选三个素数和多少个底数,例如,素数p=二3,底数g=伍(底数能够任选),再选取二个神秘整数a=陆,总括A=g^a
mod p=八,然后大声告诉小红:p=2三,g=五,A=八;

小红收到小明发来的p,g,A后,也选二个机密整数b=壹伍,然后总括B=g^b mod
p=1玖,并大声告诉小明:B=1九;

小明自个儿总括出s=B^a mod p=贰,小红也融洽总计出s=A^b mod p=二

,由此,最终协议的密钥s为二。

在这几个进度中,密钥二并不是小明告诉小红的,也不是小红告诉小明的,而是两者合计总括出来的。第二方只可以分晓p=2叁,g=伍,A=⑧,B=1九,由于不知底相互选的秘闻整数a=6和b=1五,由此无法估测计算出密钥贰。

用crypto模块实现DH算法如下:

constcrypto =require(‘crypto’);// xiaoming’s keys:varming =
crypto.createDiffieHellman(512);varming_keys =
ming.generateKeys();varprime = ming.getPrime();vargenerator =
ming.getGenerator();console.log(‘Prime: ‘+
prime.toString(‘hex’));console.log(‘Generator: ‘+
generator.toString(‘hex’));// xiaohong’s keys:varhong =
crypto.createDiffieHellman(prime, generator);varhong_keys =
hong.generateKeys();// exchange and generate secret:varming_secret =
ming.computeSecret(hong_keys);varhong_secret =
hong.computeSecret(ming_keys);// print secret:console.log(‘Secret of
Xiao Ming: ‘+ ming_secret.toString(‘hex’));console.log(‘Secret of Xiao
Hong: ‘+ hong_secret.toString(‘hex’));

运作后,能够得到如下输出:

$ node dh.js

Prime: a8224c…deead3

Generator: 02

Secret of Xiao Ming: 695308…d519be

Secret of Xiao Hong: 695308…d519be

小心每一回输出都不等同,因为素数的选料是随机的

写文件

私下认可写入是覆盖 ,可以选用append追加

方法1.fs.writeFile(path,callback);

方法2.var streamwriter = fs.createWriteStream(path);

streamwriter.write(‘xxx’,callback)      
 (以流的法子写入,防止在内部存款和储蓄器中读取过多)

 

其他文件api

检查文件、删除、重命名..

 

写2个目录树显示的兑现:

思路:通过利用fs.readdirSync

 

//打字与印刷当前目录全体文件

const fs = require(‘fs’);

const path = require(‘path’);

var target = path.join(__dirname,’./’);

function load(target,depth){

var prefix = new Array(depth+1).join(‘| ‘);

 

var dirinfo = fs.readdirSync(target);

 

var dirs = [];

var files = [];

dirinfo.forEach(info=>{

var stats = fs.statSync(path.join(target,info))

if(stats.isFile()){

 

files.push(info);

}else{

 

dirs.push(info);

}

});

 

dirs.forEach(dir=>{

console.log(`${prefix}├─${dir}`);

load(path.join(target,dir),depth+1);

});

var count = files.length;

files.forEach(file=>{

console.log(`${prefix}${–count?’├’:’└’}─${file}`);

});

};

load(target,0);

 

 

 

互联网框架

Express框架的主导是对http模块的再封装

var http = require("http");
var app = http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.end("Hello world!");
});

app.listen(3000, "localhost");

var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('Hello world!');
});

app.listen(3000);

中间件(middleware)是处理HTTP请求的函数。

app.use(function(req,res,next){

 

if(req.url == ‘/’)

{

res.end(‘Welcome to the homepage!\n’);

}else{

next();

}

});

app.use(function(req,res,next){

if(req.url == ‘/about’){

res.writeHead(200,{‘Content-Type’:’text/plain’});

}else{

next();

}

});

app.use(function(req,res){

res.writeHead(404,{‘Content-Type’:’text/plain’});

res.end(‘404 Error!\n’);

});

 

也得以这么写:(将地址写在首个参数里,那样唯有对这么些地点的伸手,才有相应的答疑)

app.use("/home", function(request, response, next) {
  response.writeHead(200, { "Content-Type": "text/plain" });
  response.end("Welcome to the homepage!\n");
});

app.use("/about", function(request, response, next) {
  response.writeHead(200, { "Content-Type": "text/plain" });
  response.end("Welcome to the about page!\n");
});

app.use(function(request, response) {
  response.writeHead(404, { "Content-Type": "text/plain" });
  response.end("404 error!\n");
});

http.createServer(app).listen(1337);

还可以这样写(*是指所有的请求都要先通过这个中间件)

app.all("*", function(request, response, next) {
  response.writeHead(200, { "Content-Type": "text/plain" });
  next();
});

app.get("/", function(request, response) {
  response.end("Welcome to the homepage!");
});

app.get("/about", function(request, response) {
  response.end("Welcome to the about page!");
});

app.get("*", function(request, response) {
  response.end("404!");
});

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有