node.js学习

简介

简单说,Node.js就是运行在服务端的 Javascript

优点:

  • 高并发
  • 适合I/O密集型应用

缺点:

  • 不适合CPU密集型应用
  • 只支持单核CPU,不能充分利用CPU
  • 可靠性低(单线程、单进程)

在Ubuntu安装:

sudo apt-get install nodejs
sudo apt-get install npm

node.js组成成分:

  • 引入required模块
  • 创建服务器
  • 接收请求与响应请求

HelloWorld

no.js写入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var http = require('http');  //载入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); //监听8888端口

// 终端打印如下信息
console.log('Server running at http://127.0.0.1:8888/');

运行:

node no.js

此时,便可访问127.0.0.1:8888

NPM

NPM是node.js的包管理工具,新版的nodejs已经集成了npm

安装模式

安装模式分为本地安装和全局安装(-g):

  • 本地安装:将安装包放在node_modules(测试发现这个文件位于~/目录下);可通过require()来引入本地安装的包
  • 全局安装:将安装包放在/usr/local或node的安装目录;可直接在命令行里使用

常用命令

安装模块(如果全局安装,只需加上-g参数):

npm install xxx

更新模块:

npm update xxx

搜索模块:

nmp search xxx

查看模块版本号:

npm list xxx

node.js交互式解释器(REPL)

类似shell,接收用户输入并执行输出;可以很好的调试JavaScript;输入node命令进入

1.声明变量

var a = 10

2.打印

console.log(a)

3.下划线变量

可以使用_获取上一个表达式结果:

1
2
3
4
5
6
7
8
9
10
> var x = 10
undefined
> var y = 5
undefined
> x + y
15
> console.log(_)
15
undefined
>

4.常用命令

  • tab:列出当前命令
  • .help:列出使用命令

模块

ES6之前,node采用的是CommonJS规范,require函数用于在当前模块中加载和使用其他模块,传入一个模块名,返回一个模块导出对象(exports);模块名可使用相对路径或绝对路径;模块名中的.js扩展名可省略;exports对象是当前模块的导出对象,用于导出模块公有方法和属性,来提供对外访问接口

example:

./main.js
./mod.js

main.js:

1
2
3
4
var a = require('./mod');

console.log(a.add());
console.log(a.add());

mod.js:

1
2
3
4
5
6
7
var i = 0;

function add(){
return i++;
}

exports.add = add;

在mod.js中定义了一个add函数,并用exports导出,这样main.js导入这个模块后便会返回exports对象,之后定义的对象便可调用add方法

在命令行输入node mainnode main.js可看到打印结果

nodejs每个文件就是一个模块,nodejs会为每个js文件生成一个module对象,这个module对象会有一个exports属性,并且这个exports属性是一个空对象;module.exportsexports其实是一样的,都是空对象:

console.log(exports === module.exports)

而它俩的关系是:

exports是一个指向module.exports对象的变量

文件操作

需导入内置的fs模块

读文件

1.阻塞实现
1
2
3
4
var fs = require('fs');
var data = fs.readFileSync('/etc/passwd');
console.log(data.toString())
console.log('end')

运行上面代码后,会先输出/etc/passwd的内容再输出end,即顺序执行

2.非阻塞实现

node.js的异步编程依托于回调来实现(反过来不对);回调函数一般作为函数的最后一个参数出现

1
2
3
4
5
6
7
8
var fs = require('fs');

fs.readFile('/etc/passwd', function (err, data) {
if (err) return console.error(err);
console.log(data.toString());
});

console.log("end");

会先输出end,再输出文件内容

网络操作

NodeJs本来的用途是编写高性能的web服务器

服务端

上面的HelloWorld中,创建了一个简单的web服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var http = require('http');  //载入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); //监听8888端口

// 终端打印如下信息
console.log('Server running at http://127.0.0.1:8888/');

http模块创建的HTTP服务器在接收到完整的请求后,就会调用回调函数;HTTP响应本质上是一种数据流,由headers和body组成,这里使用了response对象来写入

客户端

GET请求

使用http.request请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var http = require('http');

//请求参数
var options = {
hostname: '127.0.0.1',
port: 80,
path: '/phpinfo.php',
method: 'GET',
headers:{

}
}
//get请求
var request = http.request(options, function (res){
console.log(res.statusCode); // 状态码
console.log(res.headers); //响应头
//响应体
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});

});

//捕获异常
request.on('error', function (e) {
console.log('problem with request: ' + e.message);
});

request.end(); //结束请求

但这样有些麻烦,http提供了便捷的API:http.get

1
2
3
4
5
6
7
8
var http = require('http');

var re = http.get('http://127.0.0.1/phpinfo.php', function(res){
console.log(res.headers);
res.on('data', function(chunk){
console.log(chunk.toString());
})
});
POST请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
var http = require('http');  

var qs = require('querystring');

//这是需要提交的数据
var post_data = {
t: 'phpinfo();'
};

//转换参数格式
var content = qs.stringify(post_data);
console.log(content);

//请求头
var options = {
hostname: '127.0.0.1',
port: 80,
path: '/shell.php',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
};

//请求
var req = http.request(options, function (res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});

//监听错误信息
req.on('error', function (e) {
console.log('problem with request: ' + e.message);
});

// 将数据写入请求体
req.write(content);

req.end();

上面的querystring模块用于实现URL参数字符串与参数对象的互相转换

nodejs使用了chunk(分块传输编码),至于是啥可看下这位大佬的文章

https://blog.csdn.net/yankai0219/article/details/8269922