STAY HUNGRY , STAY FOOLISH.

求知若饥,虚心若愚。

       浏览:

初识Node.js

1.什么是Node.js?

Node.js指可以用JavaScript语言编写服务器的解析器。
如HTML里面的JavaScript,浏览器充当JavaScript语言的解析器,给JS提供document,location,history之类的内置对象。同理,Node.js给JS提供fs,http,events之类的内置对象。


2.Node.js特点

毕竟是初识,高大山的特点我还不清楚,什么异步IO,事件机制,毕竟没接触过。但是我能根据web前端的JavaScript特性,去猜测其特性。
JavaScript语言其特点是依赖相关的解析器,能使用相关的API及内置对象

1)浏览器的JavaScript

document可以操作DOM,location可以跳转页面,history可以控制页面的前进后退等,这些都是基于window对象。你可以直接在浏览器的控制台里面调取其API和内置对象。

window


2)WebView的JavaScript

WebView简单理解就是拥有浏览器的内核的容器,比如在原生App、PC客户端、机顶盒都有它的存在。

2.1)Cordova的JavaScript

doucment可以操作手机的核心设备功能,如:地理定位、加速器、联系人、声音和振动等。

cordova

2.2)微信小程序的JavaScript

没有document、window对象,因此无法使用DOM操作,更别说使用JQuery、Zepto之类的js框架。
wx可以发起请求、拨打电话、获取位置、跳转页面、使用Canvas画布等。
微信小程序可以说是把浏览器的相关特性和Cordova相关特性结合起来,只针对微信App内部使用。

wx


3)Node.js的JavaScript

上面说了那么多解析器上的JavaScript,那么Node.js的JavaScript的特点是什么呢?
答案很简单,还是看Node.js给我们提供哪些好用的API和内置对象。
引用别人写的一句话:

NodeJS的作者说,他创造NodeJS的目的是为了实现高性能Web服务器,他首先看重的是事件机制和异步IO模型的优越性,而不是JS。但是他需要选择一种编程语言实现他的想法,这种编程语言不能自带IO功能,并且需要能良好支持事件机制。JS没有自带IO功能,天生就用于处理浏览器中的DOM事件,并且拥有一大群程序员,因此就成为了天然的选择。

我还没真正写过Node.js,只能从别人的话语里明白Node.js最大的特点就是为了实现高性能Web服务器
请看截图:
ali


3.安装Node.js

安装Node.js,去其官网下载即可,官网地址:https://nodejs.org/en/

node.js

安装成功后,在控制台输入:

1
node -v 

出现版本号v6.9.2,即安装成功


4.执行JavaScript文件

安装好node后,可以直接使用node命令执行js文件。
比如你在桌面新建一个node.js文件,在里面console一句话,然后使用该命令:

1
node node.js

打印出console里面的Hello,Node.js!,则表示执行了该文件。

success


5.创建第一个服务器应用(http)

继续在刚刚的node.js里面添加代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
//引入required模块
var http=require("http");
//创建服务器
http.createServer(function(request,response){
//发送HTTP头部
//HTTP 状态值: 200 OK
//内容类型: text/plain
response.writeHead(200,{'Content-Type':'text/plain'});

//发送响应数据"Hello World"
response.end('Hello World\n');
}).listen(8888);
console.log('Server running at http://127.0.0.1:8888');

first-server

然后执行node.js文件,服务器启动成功后,在浏览器能看到Hello World。


6.NPM包管理工具

NPM是随同NodeJS一起安装的包管理工具,需要使用哪个框架,直接从NPM官网下载使用。
常见命令:

1
2
3
4
5
6
7
8
//安装模块到全局
sudo npm install 模块名 -g

//卸载模块
sudo npm uninstall 模块名 -g

//更新模块
sudo npm update 模块名 -g

7.调试JavaScript代码

浏览器的控制台可以输出我们想调试的内容,那么node同样也有此功能。
输入node,可以进行简单的加减运算,声明变量,输出它等。
按两次ctrl+c退出node。
console


8.读取本地文件(fs)

创建一个文件node.txt,输入Hello,Node.js!,保存。
继续在node.js文件里面输入代码:

1
2
3
4
5
6
7
8
9
10
11
12
var fs=require("fs");
//阻塞是按顺序执行的 不推荐
var data=fs.readFileSync('node.txt');
console.log(data.toString());
console.log('程序执行结束');

//非阻塞是不需要按顺序的 推荐
fs.readFile('node.txt',function(err,data){
if(err)return console.log(err);
console.log(data.toString());
});
console.log('程序执行结束');

9.事件驱动模型(events)

JavaScript是一个单线程语言,从上到下依次执行。同理Node.js是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高。

event-loop

Node.js 使用事件驱动模型,当web服务接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。
当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。
这个模型非常高效可扩展性非常强,因为web服务一直接受请求而不需要等待任何读写操作。
(这也被称之为非阻塞式IO或者事件驱动IO)
在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。

引用的可能难理解,举个例,同事们一起聚餐就是非阻塞IO。
从同事们一起到餐厅的那刻起,开启了一个吃饭事件
大家关系好,要走一起走,但是有想保持身材的吃得快,有想喝酒的吃得慢,谁先吃完谁后吃完都不确定,这时开启了多个异步事件,大家都这样循环着等最后一个吃完;
等大家吃好了,账也结了,大家从餐厅离开的那个起,关闭了该吃饭事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var events=require('events');
var eventEmitter=new events.EventEmitter();
var eatStart=function(){
console.log('进餐厅');
eventEmitter.emit('people1');
};
var people1=function(){
console.log('小红吃得快');
eventEmitter.emit('people2');
};
var people2=function(){
console.log('小明吃得慢');
};
//统一注册事件
eventEmitter.on('eatStart',eatStart);
eventEmitter.on('people1',people1);
eventEmitter.on('people2',people2);
//触发事件
eventEmitter.emit('eatStart');
console.log('离开餐厅');

控制台输出结果:

1
2
3
4
进餐厅
小红吃得快
小明吃得慢
离开餐厅

大多数时候我们不会直接使用 EventEmitter,而是在对象中继承它。包括 fs、net、 http 在内的,只要是支持事件响应的核心模块都是 EventEmitter 的子类。


10.创建服务器与客户端

服务器就是响应数据,给你东西的;
客户端就是接受数据,你看到的。

目前最主流的三个Web服务器是Apache、Nginx、IIS。

使用Node创建一个Web服务器,特别简单,新建个server.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var http = require('http');
var fs = require('fs');
var url = require('url');

http.createServer(function(request,response){
var pathname = url.parse(request.url).pathname;
console.log('request for'+pathname+' received.');
fs.readFile(pathname.substr(1),function(err,data){
if(err){
console.log(err);
response.writeHead(404,{'Content-type':'text/html'});
}else{
response.writeHead(200,{'Content-type':'text/html'});
response.write(data.toString());
}
response.end();
});
}).listen(8081);
console.log('Server running at http://127.0.0.1:8081/');

在server.js当前目录下你可以创建很多类型的资源,如html文档、json格式的文本、图片等,
index.html、data.json、a.jpg。

然后在浏览器输入http://127.0.0.1:8081/文件名,即可在浏览器中看到你创建的文件。

除了使用浏览器访问资源外,使用Node创建一个Web客户端,新建个client.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var http = require('http');
var options = {
host:'localhost',
port:'8081',
path:'/index.html'
};
var callback = function(response){
var body = '';
response.on('data',function(data){
body += data;
});
response.on('end',function(){
console.log(body);
});
}
var req=http.request(options,callback);
req.end();

启动了server.js后,你在去执行client.js,同样能获取到那些资源。


11.用OpenSSL命令+Node实现Https

  1. 生成自己的证书
    1
    openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365
  2. 取消生成证书时验证的密码
    1
    openssl rsa -in key.pem -out newkey.pem && mv newkey.pem key.pem
  3. 创建https服务器
    a.新建js文件
    1
    2
    3
    vim server.js

    :wq

b.编写https代码

1
2
3
4
5
6
7
8
9
10
11
12
13
const https = require('https');
const fs = require('fs');

const options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
};

https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('Hello World');
}).listen(8000);
console.log('服务启动成功,请访问https://127.0.0.1:8000')

c.启动server.js,使用浏览器访问

1
sudo node server.js

效果如下:
https