Blog Logo

初识Node.js

写于2016-12-07 14:59 阅读耗时10分钟 阅读量


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

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

node -v 

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


4.执行JavaScript文件

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

node node.js

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

success


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

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

//引入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官网下载使用。 常见命令:

//安装模块到全局
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文件里面输入代码:

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。 从同事们一起到餐厅的那刻起,开启了一个吃饭事件; 大家关系好,要走一起走,但是有想保持身材的吃得快,有想喝酒的吃得慢,谁先吃完谁后吃完都不确定,这时开启了多个异步事件,大家都这样循环着等最后一个吃完; 等大家吃好了,账也结了,大家从餐厅离开的那个起,关闭了该吃饭事件

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('离开餐厅');

控制台输出结果:

进餐厅
小红吃得快
小明吃得慢
离开餐厅

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


10.创建服务器与客户端

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

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

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

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:

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. 生成自己的证书
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365

2)取消生成证书时验证的密码

openssl rsa -in key.pem -out newkey.pem && mv newkey.pem key.pem

3)创建https服务器 a.新建js文件

vim server.js

:wq

b.编写https代码

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,使用浏览器访问

sudo node server.js

效果如下: https


Headshot of Maxi Ferreira

怀着敬畏之心,做好每一件事。