Hellom's Studio.

node基础

字数统计: 1.9k阅读时长: 9 min
2020/03/20 Share

Node 的作用和应用

  • 脱离浏览器运行 JS

  • 后台API编写

  • Webpack Gulp Npm等

  • 中间层:服务器中负责IO读写的中间层服务器

Node的优势

  • 便于前端开发入门

  • 性能高

  • 利于前端代码整合

Node中间层的优势

  • 性能提高(异步IO 适合处理高并发)

  • 处理数据

  • 提高安全性

Node 模块

全局模块 (对象)

定义:何时何地都能访问,不需要引用。类似于 js 中的 document window

例如:

process.env

  • 返回用户环境信息

process.argv

  • 提供当前进程有关的消息,返回一个数组

  • 数组的第一个元素 process.argv[0]: 返回node进程的可执行文件所在的绝对路径

  • 数组的第二个元素 process.argv[1]: 返回当前执行的 JS 文件路径

系统模块

定义:需要 require(),但不需要单独下载

例如:

path: 用于处理文件路径和目录路径的实用工具

1
2
3
4
5
6
7
8
9
10
e.g.
let path = require('path');

console.log(path.dirname('/node/a/b/c/1.jpg')); // 获取目录路径 /node/a/b/c

console.log(path.basename('/node/a/b/c/1.jpg')); // 获取文件名 1.jpg

console.log(path.extname('/node/a/b/c/1.jpg')); // 获取文件扩展名 .jpg

console.log(path.resolve(__dirname, 'demo.js')); // 获取文件绝对路径

fs:用于文件读写操作

fs.readFile 接收的参数:

  • 第一个参数:需要读取的文件路径。 ==> './demo.html'

  • 第二个参数:回调函数。 ==> callback函数

1
2
3
4
5
6
7
8
9
10
11
12
13

let fs = require('fs');

// 读取文件内容

fs.readFile('./demo.html', (err, data) => {
if (err) {
console.log(err);
} else {
console.log(data); // [Buffer 61 62 63] 输出二进制内容
console.log(data.toString()); // 通过 toString() 方法转换成字符串
}
})

fs.writeFile 接收的参数:

  • 第一个参数: 需要创建的文件名称及路径。 ==> './a.txt'

  • 第二个参数: 需要写入的内容。 ==> '写入一个文件'

  • 第三个参数: 以追加方式写入文件。 ==> {flag: 'a'}

  • 第四个参数:回调函数。 ==> callback函数

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

// 写入文件内容
fs.writeFile('./a.txt', '写入一个文件', {flag: 'a'}, (err) => {
if (err) {
throw err;
}
})

自定义模块

定义:require 自己封装的模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
e.g.

// mod.js

class People {
constructor(name) {
this.name = name;
}
}

module.exports = People; // 输出 People 这个类


// demo.js

let Mod = require('./mod'); // 引入自定义的模块

let p = new Mod('张三'); // 实例化

console.log(p.name); // 张三

关于引入的文件路径的问题:

  • require('./mod'): 写路径的话 就会在当前文件夹中寻找这个模块

  • require('mod'): 只写模块名的话 就会在 node_modules 文件夹寻找

HTTP模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
e.g.
// 简单的 HTTP 模块使用例子

let http = require('http');
let fs = require('fs');

http.createServer((req, res) => {

fs.readFile(`./${req.url}`, (err, data) => {

if (err) {
res.writeHead(404);
res.end('404');
} else {
res.writeHead(200);
res.end(data);
}

})
}).listen(8888);

Node 中的数据交互

GET 请求

  • 数据是放在url地址栏进行传输的

  • 放在报文的头部 容量:< 32K

1
2
3
4
5
6
7
8
e.g.
<!-- demo.html 简单的form表单get的流程 -->

<form action="http://localhost:8888/apis" method="GET">
用户名:<input type="text" name="userName"><br>
密码:<input type="password" name="password" id=""><br>
<input type="submit" value="提交">
</form>
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
e.g.
// demo.js

let http = require('http'); // 引入http模块

let url = require('url'); // 引入url模块

http.createServer((req, res) => {

console.log(req.url); // 获取请求的URL地址:/apis?userName=ceshi&password=123456

console.log(url.parse(req.url,true))

/* 返回信息
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: '?userName=1111&password=33333',
query:
[ Object: null prototype] { userName: '1111', password: '33333' },
pathname: '/apis',
path: '/apis?userName=1111&password=33333',
href: '/apis?userName=1111&password=33333' }
*/

}).listen(8888)

url.parse 接收的参数:

  • 第一个参数:获取请求的URL地址。 ==> /apis?userName=ceshi&password=123456

  • 第二个参数:是否要自动处理好query里面的值(parseQueryString) => true

POST 请求

  • 数据是放在body里面进行传输的

  • 放在报文的主体里 容量大:< 2G

1
2
3
4
5
6
7
8
e.g.
<!-- demo.html POST -->

<form action="http://localhost:8888/apis" method="POST">
用户名:<input type="text" name="userName"><br>
密码:<input type="password" name="password" id=""><br>
<input type="submit" value="提交">
</form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let http = require('http');
let queryString = require('querystring'); // 用于解析和格式 url

http.createServer((req, res) => {

let result = [];

req.on('data', buffer => {
result.push(buffer);
})

req.on('end', () => {

let data = Buffer.concat(result).toString(); // userName=zhangsan&password=345345345

console.log(queryString.parse(data)); // [Object: null prototype] { userName: '21312312', password: '3444' }
})

}).listen(8888)

实现简单的登录注册案例

接口

什么是接口(API):不同功能层之间的通信规则

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
 <style>
body {
background-color: #34495e;
margin: 0;
padding: 0;
}

.content {
width: 300px;
background: #191919;
padding: 40px;
border-radius: 5px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}

h2 {
text-transform: uppercase;
color: #fff;
font-weight: 400;
letter-spacing: 2px;
}

input[type='text'],
input[type='password'] {
width: 250px;
height: 40px;
margin-bottom: 20px;
border: 1px solid #3498db;
background: #191919;
color: #fff;
text-align: center;
border-radius: 25px;
outline: 0;
}

input[type='text']:focus,
input[type='password']:focus {
width: 300px;
border: 1px solid #2ecc71;
}

button {
width: 100px;
height: 40px;
margin-bottom: 15px;
outline: 0;
background: #191919;
border-radius: 25px;
}

button:first-of-type {
border: 0;
color: #2ecc71;
border: 1px solid #2ecc71;
}

button:first-of-type:hover {
background: #2ecc71;
color: #fff;
}

button:last-of-type {
color: #e74c3c;
border: 1px solid #e74c3c;
}

button:last-of-type:hover {
background: #e74c3c;
color: #fff;

}
</style>

<script src="jquery.min.js"></script>
<script>
$('#login').on('click', () => {
$.ajax({
url: "/login",
method: 'GET',
data: {
username: $('#username').val(),
password: $('#password').val()
},
dataType: 'json',
success(res) {
alert(res.msg);
if (!res.status) {
location.href = 'href.html';
}

}
})
})

$('#reg').on('click', () => {
$.ajax({
url: "/reg",
method: 'POST',
data: {
username: $('#username').val(),
password: $('#password').val()
},
dataType: 'json',
success(res) {
alert(res.msg)
}
})
})
</script>

<div class="content">
<h3>后台登录系统</h3>
<input type="text" id="username" placeholder="用户名">
<input type="password" id="password" placeholder="密码">
<button id="login">登录</button>
<button id="reg">注册</button>
</div>
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
let http = require('http');
let url = require('url');
let querystring = require('querystring');
let fs = require('fs');

let user = { admin: 123456 } // 模拟数据库数据
http.createServer((req, res) => {

//获取数据
let path, getData, postData;

if (req.method == 'GET') {
// 获取接口地址、用户名密码
let { pathname, query } = url.parse(req.url, true);
path = pathname;
getData = query;
complete();

} else if (req.method == 'POST') {

let arr = [];

// post 数据是一段一段获取的 将数据 push 到 arr 中
req.on('data', buffer => {
arr.push(buffer);
})

req.on('end', (err, data) => {
if (err) {
res.end('404');
} else {
path = req.url;
postData = querystring.parse(Buffer.concat(arr).toString());
complete();
}
})
}

// 处理数据

function complete() {
// 登录
if (path == '/login') {
let { username, password } = getData;
res.writeHead(200, { 'Content-Type': 'text/plain;charset=utf-8' });
if (!user[username]) {
res.end(JSON.stringify({
status: 1,
msg: '用户名不存在!'
}))
} else if (user[username] != password) {
res.end(JSON.stringify({
status: 2,
msg: '密码错误!'
}))
} else {
res.end(JSON.stringify({
status: 0,
msg: '登录成功'
}))
}
// 注册
} else if (path == '/reg') {

let { username, password } = postData;

res.writeHead(200, { 'Content-Type': 'text/plain;charset=utf-8' });

if (user[username]) {
res.end(JSON.stringify({
status: 0,
msg: '用户已存在!'
}))
} else {
res.end(JSON.stringify({
status: 1,
msg: '注册成功!'
}))
user[username] = password;
}

} else {
// 读取文件
fs.readFile(`./${req.url}`, (err, data) => {
if (err) {
res.writeHead(404);
res.end('404');
} else {
res.writeHead(200);
res.end(data);
}
})
}
}
}).listen(8888)

npm 相关命令

  • npm init: 初始化 生成 package.json 文件

  • npm install jquery: 安装 jquery

  • npm uninstall jquery: 卸载 jquery

  • cnpm install: 国内 npm 镜像

  • npm i -g nodemon: Node自动重启工具

使用以下命令即可安装:

npm install -g cnpm --registry=https://registry.npm.taobao.org

CATALOG
  1. 1. Node 的作用和应用
  2. 2. Node的优势
  3. 3. Node中间层的优势
  4. 4. Node 模块
    1. 4.1. 全局模块 (对象)
    2. 4.2. 系统模块
    3. 4.3. 自定义模块
    4. 4.4. HTTP模块
  5. 5. Node 中的数据交互
    1. 5.1. GET 请求
    2. 5.2. POST 请求
  6. 6. 实现简单的登录注册案例
    1. 6.1. 接口
  7. 7. npm 相关命令