node.js学习笔记

0、nodeJs特征

单线程、非阻塞I/O、事件驱动

1、node里面的全局对象

JavaScript有且仅有一个全局对象,在浏览器中,叫window对象。而在Node.js环境中,也有唯一的全局对象,但不叫window,而叫global

1
2
3
4
console.log(__dirname); //输出F:\node学习\beginning    获取当前文件所在的路径

console.log(__filename);//输出F:\node学习\beginning\test.js 获取当前文件路径

2、模块的引入

一个模块想要对外暴露变量(函数也是变量),可以用module.exports = variable;,一个模块要引用其他模块暴露的变量,用var ref = require(‘module_name’);就拿到了引用模块的变量。

2.1 单个函数的export

1
2
3
4
5
6
7
8
9
10
11
12
13
//这是count.js
function counter(arr){
console.log(`the lenght of arr is ${arr.length}`);
}
module.exports = counter;


//这是test.js
var counter = require('./count.js'); //引入模块
const arr = [1,2,3,4,5,6,7];
counter(arr);

node test.js //输出 the lenght of arr is 7

2.2 export多个函数或者变量

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
// 这是count.js
function counter(arr){
console.log(`the lenght of arr is ${arr.length}`);
}
function test(){
console.log('hello world');
}
const a = 10;
module.exports.counter = counter;
module.exports.test = test;
module.exports.a = a;
ps: 此处可以简写为
module.exports = {
counter,
test,
a
}



//这是test.js
var shuffle = require('./count.js');
console.log(shuffle.a);
shuffle.test();

node test.js //输出 10 'hello world'


//test.js里面的require可以直接引入需要的函数或者数值
var a = require('./count.js').a;
console.log(a);// 10

2.3模块化编程思想

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//这是server.js
let http = require('http');
let fs = require('fs');
function server(){
let server = http.createServer((request, response) => {
response.writeHead(200, {'Content-Type': 'text/html'});//设置响应头
let data = fs.createReadStream(__dirname + '/transition01.html','utf8');
data.pipe(response);
});
server.listen(3000);
console.log('server start at localhost:3000');
}
exports.server = server;

//这是app.js
var server = require('./server.js');
server.server(); //输出 'hello world'

2.4 require的各种写法

直接require文件名字

1
const foo = require('foo.js');  // 这种写法将直接从node_modules文件夹中查找对于的文件

直接require一个文件夹(即没有文件后缀)

1
2
3
4
5
6
7
8
const foo = require('foo');  //  直接从node_modules中找到foo文件夹执行里面的index.js

//如果foo文件夹里面没有index.js则必须要有package.json文件,里面指定了入口文件
{
'name' : 'foo',
'version' : '1.1.1',
'main' : 'xxx.js' // 必须要有main这个字段,里面对应的值是执行文件的文件名字
}

如果require的模块与系统内置模块名字冲突,系统的模块会覆盖自定义的模块

3、events (事件)

1
2
3
4
5
6
let events = require('events'); //引入事件库
var myEvents = new events.EventEmitter(); //创建一个EventEmitter实例
myEvents.on('someEvent',function(data){ //someEvent是指某个事件例如click ,data是传入的数据
console.log(data);
})
myEvents.emit('someEvent', 'hello world'); //手动触发函数

4、文件系统

4、1读取文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//同步读取文件
let fs = require('fs'); // 引入文件库
let txt = fs.readFileSync('./file.txt','utf-8'); //readFileSync接受两个参数,第一个是文件路径,第二个是文件的编码格式
console.log(txt); //输出‘hello world’

//这是file.txt里面的内容
hello world


//异步读取文件
let fs = require('fs');
fs.readFile('aaa.txt','utf-8',(err,data) => {
console.log(err); //null
console.log(data); // 'hello worldd'
});
console.log('读取文件成功');
输出为
读取文件成功
null
hello world

4、2创建文件并写入内容

1
2
3
4
5
6
7
8
9
//同步创建文件
let fs = require('fs');
let txt = fs.readFileSync('./file.txt');
fs.writeFileSync('aaa.txt',txt); //把file.txt里面的内容写入到新建的aaa.txt里面

//异步创建文件
fs.writeFile('aaa.txt',data,() => {
console.log('txt file has been created');
});

4、3删除文件

1
2
3
4
5
6
7
8
9
10
11
12
13
//同步删除
let fs = require('fs');
fs.unlinkSync('server.js');

//异步删除
let fs = require('fs');
fs.unlink('aaa.txt',() => {
console.log('删除成功');
});
console.log('finished');
输出
finished
删除成功

4、4创建文件夹和删除文件夹

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
//同步创建
let fs = require('fs');
fs.mkdirSync('aaa');


//异步创建
let fs = require('fs');
fs.mkdir('test', () => {
console.log('创建成功');
});

//同步删除文件夹
let fs = require('fs');
fs.rmdirSync('aaa');

//异步删除
let fs = require('fs');
fs.rmdir('test',() => {
console.log('删除成功');
});


//demo,创建文件夹,并在里面新建文件
let fs = require('fs');
fs.mkdir('test',() => {
fs.writeFile('test/aaa.txt','hello world',() => {
console.log('成功创建文件夹和文件');
});
});

4.5 获取文件的详细信息

如果我们要获取文件大小,创建时间等信息,可以使用fs.stat(),它返回一个Stat对象,能告诉我们文件或目录的详细信息:

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
let fs = require('fs');
fs.stat('./test.txt',((err,data) => {
console.log(data);
}))

//输出以下内容
Stats {
dev: 563682,
mode: 33206,
nlink: 1,
uid: 0,
gid: 0,
rdev: 0,
blksize: undefined,
ino: 1688849860428397,
size: 23,
blocks: undefined,
atimeMs: 1526475120655.8008,
mtimeMs: 1526475270067.3467,
ctimeMs: 1526475270067.3467,
birthtimeMs: 1526475120655.8008,
atime: 2018-05-16T12:52:00.656Z,
mtime: 2018-05-16T12:54:30.067Z,
ctime: 2018-05-16T12:54:30.067Z,
birthtime: 2018-05-16T12:52:00.656Z
}

4.6 获取一个文件夹里面所有文件(包括文件夹里面的文件夹)

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

http.createServer((req, res) => {
if (req.url === '/favicon.ico') {
return;
}
fs.readdir('../1、http模块', (err, data) => {
console.log(data); // 返回的data是个数组
});
res.end('success');
}).listen(3000, '127.0.0.1');

5、stream (流)

什么是流?流是一种抽象的数据结构。想象水流,当在水管中流动时,就可以从某个地方(例如自来水厂)源源不断地到达另一个地方(比如你家的洗手池)。我们也可以把数据看成是数据流,比如你敲键盘的时候,就可以把每个字符依次连起来,看成字符流。这个流是从键盘输入到应用程序,实际上它还对应着一个名字:标准输入流(stdin)。如果应用程序把字符一个一个输出到显示器上,这也可以看成是一个流,这个流也有名字:标准输出流(stdout)。流的特点是数据是有序的,而且必须依次读取,或者依次写入,不能像Array那样随机定位。

5.1 读取流

1
2
3
4
5
6
let fs = require('fs');
let myFile = fs.createReadStream(__dirname + '/test.txt');
myFile.on('data',(res) => { // 'data',代表是接受收据时执行的函数
console.log(res); //<Buffer 69 6e 70 75 74 20 69 6e 70 75 74 20 69 6e 70 75 74 20 69 6e 70 75 74>
});

5.2 写入流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let fs = require('fs');
let myReadFile = fs.createReadStream(__dirname + '/test.txt');
myReadFile.setEncoding('utf8');
let myWriteFile = fs.createWriteStream(__dirname + '/new.txt');
myReadFile.on('data',(res) => {
myWriteFile.write(res);
});



//利用管道写入流
let fs = require('fs');
let readStream = fs.createReadStream(__dirname + '/count.js');
let writeStream = fs.createWriteStream(__dirname + '/a.js');

readStream.pipe(writeStream);

6、http模块

6.0 get和post请求区别

get请求数据在URL中,post请求数据不在URL中
post接收数据比get大很多

6.1 创建web服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//初体验
// 引用模块
let http = require('http');

//创建一个服务器,回调函数表示收到请求后做的事,request是请求,response是响应
let server = http.createServer((request, response) => {
console.log(`服务器已经打开${request.url}`);
response.end('完毕');//必须要有end,不然一直在加载
})

server.listen(3000, '127.0.0.1');



let http = require('http'); //引入http模块
let server = http.createServer((request, response) => {
response.writeHead(200, {'Content-Type': 'text/plain'});//设置响应头
response.write('hello from application');
response.end('end');
}); //创建server服务器
server.listen(3000);//监听3000端口
console.log('server start at localhost:3000');

6.2 响应JSON

1
2
3
4
5
6
7
8
9
10
11
12
13
let http = require('http');
let server = http.createServer((request, response) => {
response.writeHead(200, {'Content-Type': 'application/json'});//设置响应头
let data = {
name: 'xyp',
sex: 'man',
age: 25,
job: 'developer'
}
response.end(JSON.stringify(data));
});
server.listen(3000);
console.log('server start at localhost:3000');

输出为

6.3 响应HTML页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//直接把html写在变量里面
let http = require('http');
let server = http.createServer((request, response) => {
response.writeHead(200, {'Content-Type': 'text/html'});//设置响应头
let data = `<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<p>hello world</p>
</body>
</html>`;
response.end(data);
});
server.listen(3000);
console.log('server start at localhost:3000');

输出为

1
2
3
4
5
6
7
8
9
10
//读取外部文件
let http = require('http');
let fs = require('fs');
let server = http.createServer((request, response) => {
response.writeHead(200, {'Content-Type': 'text/html'});//此处设置为‘text/plain’的话,浏览器将不会解析为html,会变成纯文本输出
let data = fs.createReadStream(__dirname + '/transition01.html','utf8');
data.pipe(response);
});
server.listen(3000);
console.log('server start at localhost:3000');

7、路由

7.1 实现一个简单的路由

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
//app.js
var startServer = require('./server.js');
startServer.startServer();

//server.js
var http = require('http');
var fs = require('fs');

function startServer() {
var onRequest = function(request, response) {
console.log(request.url); //输出的是localhost:3000/admin ,3000后面的内容,例如本例输出的是‘/admin’
if (request.url === '/' || request.url === '/home') {
response.writeHead(200, { 'Content-Type': 'text/html' });
fs.createReadStream(__dirname + '/index.html', 'utf8').pipe(response);
} else if (request.url === '/review') {
response.writeHead(200, { 'Content-Type': 'text/html' });
fs.createReadStream(__dirname + '/review.html', 'utf8').pipe(response);
} else if (request.url === '/api/v1/records') {
response.writeHead(200, { 'Content-Type': 'application/json' });
var jsonObj = {
name: "hfpp2012"
};
response.end(JSON.stringify(jsonObj));
} else {
response.writeHead(404, { 'Content-Type': 'text/html' });
fs.createReadStream(__dirname + '/404.html', 'utf8').pipe(response);
}
}

var server = http.createServer(onRequest);

server.listen(3000, '127.0.0.1');
console.log('Server started on localhost port 3000');
}

exports.startServer = startServer;

8、express框架的使用

8.1 express创建web服务

1
2
3
4
5
6
7
8
const express = require('express');
let server = express();

server.use('/a.html', (req, res) => {
res.send('hello world');
res.end();
}) // 用use处理请求
server.listen('8080');

node.js学习笔记
https://xypecho.github.io/2018/05/14/node-js学习笔记/
作者
很青的青蛙
发布于
2018年5月14日
许可协议