node.js 初识node.js,运行在服务端的 JavaScript

Posted IT_Holmes

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了node.js 初识node.js,运行在服务端的 JavaScript相关的知识,希望对你有一定的参考价值。

1.nodejs API

1.1 nodejs API 详细介绍

node.js API接口

有一些常用的内置API方法,非常实用,如果你的模块是全局模块,直接用就可以了,如果不是,必须要先要加载一下,require(’ 内容 ') 函数 。

例如:
全局模块:process
process模块在使用的时候无需通过require()函数来加载该模块,直接使用。

不是全局模块:fs模块(Files System)
fs模块,使用时必须通过require()函数来加载该模块,就能使用。格式:var fs = require( ‘fs’ );

具体的模块可以在node.js官方的API接口看到。

1.2 API的稳定性

我们在看API时候,看到稳定性,如下图:
在这里插入图片描述
稳定性:0 ,(英文:Stability:0)

表示该API已经过时了,已经废弃掉了。

稳定性:1 ,(英文:Stability:1)

表示该API正在开发测试当中。

稳定性:2 ,(英文:Stability:2)

表示该API是稳定的API可以直接在工程项目中使用。。

下图是官方给出的一个稳定性解释:
在这里插入图片描述

1.3 nodejs API的使用

我们在官方API找到fs的writeFile函数方法,来查看怎么使用,其他的函数也是一样的。
下图,[, ]中的是可以忽略的,类型也在下面标写了,其中Buffer类型表示的是一个字节数组。

在这里插入图片描述

2. node.js 单线程(非阻塞IO)

2.1 node.js 栈

因为JS单线程的,所以nodejs也一样,每一个要 被执行的被调函数 要放入到一个栈中,执行时会调出,进入WEB APIs里面执行,执行完后放到一个队列中,等栈中所有内容都执行完后(包括main()方法),再将队列中的被调函数中的方法放入到栈中执行。
在这里插入图片描述
一个栈的案例图示:
这里函数执行时,是从上往下,依次调出。
在这里插入图片描述
如果不断往栈中添加函数,会导致栈的异常(Maximum call stack size exceeded.)。
在这里插入图片描述

2.2 node.js 同步阻塞

同步阻塞,理解起来也很简单,上面的例子,是不断在在栈中叠加,原因是它们是一起的,相互之间有存在调用。

同步阻塞,就是互不相干的调用函数,过程就是第一个调用函数进入栈中,等待结果,完成后,调出栈,再执行第二个,依次类推。见下图:
在这里插入图片描述

2.3 node.js 异步回调

首先,setTimeout(callback)进入栈,然后调入到WEB APIs中,执行。
在这里插入图片描述
此外,在WEB APIs调动时,栈就会继续调用其他方法。
在这里插入图片描述
WEB APIs中的函数执行完就调入到队列中,这里可能会有多个函数进入WEB APIs ,谁先执行完,谁先进入队列等待。
在这里插入图片描述
当栈为空时,就会调用队列中的内容,依次调用,从第一个开始。
在这里插入图片描述
可以使用loupe来测试一下。

看懂上面4个图就知道,JS代码到底是怎么执行的了。

3.node.js fs 写文件和读文件

写文件例子:
对于fs.writeFile()的方法,必须了解熟悉。

//写文件
var fs = require('fs');
var msg = '123456';

fs.writeFile('./hello.txt',msg,'utf8',function (err){
	// 如果err === null ,表示写入文件成功,没有错误!
	// 只要err 里面不是null,就表示写入文件失败了!
	if (err) {
		console.log('写入文件错误!' + err);
	}else{
		console.log('ok');
	}
});

读文件:
读文件fs.readFile()方法,

//读文件操作
var fs = require('fs');
fs.readFile('./hello.txt',function(err,data){
	if (err) {
		throw err;
	}else{
		console.log(data);
	}
	//data 参数的数据类型是一个Buffer对象,里面保存一个个的字节组。
	//把buffer对象转换为字符串,调用toString方法。
	//调用Buffer对象的toString()方法的时候,不传utf8参数,默认也会utf8。
	console.log(data.toString('utf8'));
});

也可以在参数直接设置utf8来操作:
var fs = require('fs');
fs.readFile('./hello.txt','utf8',function(err,data){
	if (err) {
		throw err;
	}else{
		console.log(data);
	}
});

4.node.js 执行路径问题

很多时候,在不同的路径下,使用node.js执行js文件,可能会报错提示找不到文件,这就是路径问题的错误。
例如:
这里的./相对路径,相对的是在当前执行命令下的路径!!而不是与js文件相同目录下。
下面文件如果放置在D盘,去C盘执行,就会找不到hellow.txt 文件,因为在C盘没有hellow.txt,hellow.txt是在D盘放置。

//这里的./相对路径,相对的是在当前执行命令下的路径!!而不是与js文件相同目录下的路径。
fs.readFile('./hellow.txt','utf8',function(err,data){
	if(err){
		throw err;
	}
	console.log(data);
});

为了解决上面这个困扰,可以使用__dirname和__filename。

__dirname:表示当前js文件所在的目录。
__filename:表示当前js文件的完整路径。

将上面代码进行修改:

var fs = require('fs');
//这里的\\\\是转义字符 + \\ 。
var filename = __dirname + '\\\\' + 'hello.txt';
// 这里的./相对路径,相对的是在当前执行命令下的路径!!而不是与js文件相同目录下的路径。
fs.readFile(filename,'utf8',function(err,data){
	if(err){
		throw err;
	}
	console.log(data);
});

这样就可以在其他的路径目录下来执行了,不会找不到hello.txt文件。

在node.js API上,可以查看到Globals(全局变量),下可以看到这两个变量的解释,__dirname和__filename不算是全局变量,算是本地的。

5. node.js Path模块

Path模块是内置模块,这里只详细介绍一下path.join()方法,可以去node.js API 查看Path模块

例如:
因为path是内置模块,所以需要require(‘path’),来进行加载。

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

var filename = path.join(__dirname,'hello.txt');

fs.readFile(filename,'utf8',function(err,data){
	if(err){
		throw err;
	}
	console.log(data);
});

6. node.js 创建文件夹

通过使用fs.mkdir()方法来实现执行。

对于镶嵌的文件夹,例如:文件夹1里面包含文件夹2,文件夹2里面又包含文件夹3等等,这种情况,可以使用镶嵌fs.mkdir()方法的回调函数来实现。

var fs = require('fs');
fs.mkdir('./dir1',function(err){
	if (err) {
		throw err;
	}
	fs.mkdir('./dir1/dir2',function(err){
		if (err) {
			throw err;
		}
		fs.mkdir('./dir1/dir2/dir3',function(err){
			if (err) {
				throw err;
			}
		});
	});
});

7.node.js http服务程序

7.1 node.js http的四个步骤

这里大体分为四个部分:

1.加载http模块。
2.创建一个http服务对象。
3.监听用户的请求事件(request事件)。
4.启动服务。

执行后,使用node命令执行该js文件,然后直接在浏览器上面访问http://localhost:8080,就可以看到自己想看的内容。
案例:

//1.加载http模块。
var http = require('http');
//2.创建一个http服务对象
var server = http.createServer();
//3.监听用户的请求事件(request事件)
//request是req,这个对象包含了用户请求报文中的所有内容。
//response是res,这个对象用来相应用户的一些数据,当服务器向客户端响应数据时,必须使用response对象。
server.on('request',function(req,res){
	
	res.write('Hello World!');
	//对于每一个请求,服务器必须结束响应,否则客户端 (浏览器)会一直等待服务器响应结束。
	res.end();
});


//4.启动服务
server.listen(8080,function(){
	console.log('服务器启动了,请访问:http://localhost:8080');
});

7.2 node.js request的编码和Content-Type

通过设置request响应头的,来设置格式和编码。

Content-Type:用于定义用户的浏览器或相关设备如何显示将要加载的数据,或者如何处理将要加载的数据
text/html的意思是将文件的content-type设置为text/html的形式,浏览器在获取到这种文件时会自动调用html的解析器对文件进行相应的处理。
text/plain的意思是将文件设置为纯文本的形式,浏览器在获取到这种文件时并不会对其进行处理。

案例:

//1.加载http模块。
var http = require('http');
//2.创建一个http服务对象
var server = http.createServer();
//3.监听用户的请求事件(request事件)
//request是req,这个对象包含了用户请求报文中的所有内容。
//response是res,这个对象用来相应用户的一些数据,当服务器向客户端响应数据时,必须使用response对象。
server.on('request',function(req,res){
	
	//设置响应头设置utf-8编码。
	// Content-Type:用于定义用户的浏览器或相关设备如何显示将要加载的数据,或者如何处理将要加载的数据
	// text/html的意思是将文件的content-type设置为text/html的形式,浏览器在获取到这种文件时会自动调用html的解析器对文件进行相应的处理。
	// text/plain的意思是将文件设置为纯文本的形式,浏览器在获取到这种文件时并不会对其进行处理。
	// res.setHeader('Content-Type','text/plain;charset=utf-8');
	res.setHeader('Content-Type','text/html;charset=utf-8');
	res.write('Hello <h1>World</h1>! 你好世界!');
	//对于每一个请求,服务器必须结束响应,否则客户端 (浏览器)会一直等待服务器响应结束。
	res.end();
});

//4.启动服务
server.listen(8080,function(){
	console.log('服务器启动了,请访问:http://localhost:8080');
});

7.3 node.js http对不同请求,返回不同响应

7.3.1 node.js 在终端显示路径url

再终端打印浏览器请求的路径,注意不是浏览器的console,而是服务器端的终端,这里不要混淆!!
案例:

var http = require('http');

http.createServer(function(req,res){
	//在命令终端打印路径。
	console.log(req.url);
	//结束响应。
	res.end();
}).listen(8080,function(){
	console.log("服务器启动了,请访问:http://localhost:8080");
});

在这里插入图片描述

7.3.2 node.js 响应浏览器请求不同地址的内容

案例:
使用if配合res.end()方法,end方法既可以结束响应又可以返回数据

var http = require('http');

http.createServer(function(req,res){
	//可以使用if配合res.end()方法,end方法既可以结束响应又可以返回数据。
if (req.url === '/' || req.url === '/index') {
		res.end('Hello Index!');
	}else if(req.url === '/login'){
		res.end('Hello login');
	}else if(req.url === '/register'){
		res.end('Hello register');
	}else {
		res.end('erro 404,not Found!');
	}
}).listen(8080,function(){
	console.log("服务器启动了,请访问:http://localhost:8080");
});

7.3.3 node.js 服务器端实现网页请求相应不同内容

案例 06.demo.js文件:

这个案例结合了三个模块,加上如何访问4个网页。多看注释!!!!

//加载http模块
var http = require('http');
//加载fs模块
var fs = require('fs');
//加载path模块
var path = require('path')
http.createServer(function(req,res){
	if (req.url === '/' || req.url === '/index') {
		//读取index.html	文件
		//这里读取不需要使用utf8来转换,因为将data传到浏览器,也是需要Buffer二进制码的形式。
		//当Buffer数据传到浏览器端后,如果index.html中设置了utf-8,浏览器就会识别相关内容,不会乱码。
		fs.readFile(path.join(__dirname,'demo','index.html'),function(err,data){
			if (err) {
				throw err;
			}
			//将读取到的index.html中的内容直接发送给浏览器。
			res.end(data);
		});

	}else if(req.url === '/login'){
		fs.readFile(path.join(__dirname,'demo','login.html'),function(err,data){
			if (err) {
				throw err;
			}
			res.end(data);
		});
	}else if(req.url === '/register'){
		fs.readFile(path.join(__dirname,'demo','register.html'),function(err,data){
			if (err) {
				throw err;
			}
			res.end(data);
		});
	}else {
		fs.readFile(path.join(__dirname,'demo','error(404).html'),function(err,data){
			if (err) {
				throw err;
			}
			res.end(data);
		});
	}
}).listen(1234,function(){
	//这里端口可以随便修改
	console.log('服务器启动了,请访问:http://localhost:1234');
});

上面的代码,放在了node-project目录下,这里我设置在demo目录中,里面有4个网页对应4个不同内容,如下图:
在这里插入图片描述

在这里插入图片描述
这里四个html文件对应的内容只是简单的写了一些,如下图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这样在服务器端,运行一些06.demo.js就可以实现不同的访问了。

以上多有代码,可以去GitHub上面看一下。

以上是关于node.js 初识node.js,运行在服务端的 JavaScript的主要内容,如果未能解决你的问题,请参考以下文章

node.js初识

初识node.js(通过npm下载项目依赖的包的过程)

Node.js初识

Node.js 入门:就是运行在服务端的 JavaScript

Node.js初识

Node.js 入门:运行在服务端的 JavaScript