把知识记在小本本上

将零散的知识点放在一个集中的地方,不断递归重构,形成一套为己所用的知识系统。

博客首页 | 小本本首页

同步、异步

在 node.js 中绝大多数的异步操作。

HTTP 协议

规定了浏览器和服务器之间如何进行交互。

HTTP 发展过程

1
2
3
4
HTTP 1.0 RFC-1945
HTTP 1.1 RFC-2616 持久连接(连接完了一定时间内不会马上断开)
HTTPS RFC-2818 安全协议
HTTP 2.0 RFC-7540 加密、头部压缩、服务器推送、管线操作、多路复用

HTTP 报文结构

1
2
header <= 32K
body <= 2G

HTTP 状态码

1
2
3
4
5
1xx 信息
2xx 成功
3xx 重定向(你需要的资源不在我这,在另外一个地址,你去找他要)
4xx 请求错误(404 not found,是请求错误)
5xx 服务器错误(是服务器的错误,不是你的错)

HTTP 请求方式

1
2
3
4
5
6
GET   获取
数据放在url里面传输的
1.容量小<=32K

POST 发送数据
1.容量大

http 模块

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

let server=http.createServer(function (req, res){ // request(请求), response(相应)
res.write('abc');
res.end(); // 发完东西结束请求,告诉浏览器不用等了,我发完了。
});
server.listen(8080);

fs 模块

file system。

fs.writeFile(path, data, callback);fs.readFile(path, callback);他俩就是异步操作,当然他俩也有同步的版本:fs.writeFileSyncfs.readFileSync

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const fs=require('fs');

//fs.writeFile(path, data, callback);
//fs.readFile(path, callback);

// 写入文件
fs.writeFile('./a.txt', 'asdfasdfad', err=>{
if(err){
console.log('失败', err);
}else{
console.log('成功')
}
});
// 读取文件
fs.readFile('./a.txt', (err, data)=>{ // 返回的是一个 Buffer 数据(原始的二进制数据)
if(err){
console.log('错误', err);
}else{
console.log('成功', data);
}
});

举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const http=require('http');
const fs=require('fs');

let server=http.createServer(function (req, res){
console.log(req.url);
//req.url =>'/1.html'
//=>'www/1.html'

fs.readFile(`www${req.url}`, (err, buffer)=>{ // 读取相应的文件
if(err){ // 如果请求错误
res.writeHeader(404); // 状态码
res.write('Not Found'); // 显示
res.end(); // 结束
}else{
// res.writeHeader(200); // 200 代表成功,默认是这个
res.write(buffer);
res.end();
}
});
});
server.listen(8080);

GET 请求

一次给到数据库。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form action="http://localhost:8080/aaa" method="get">
用户:<input type="text" name="username" /><br>
密码:<input type="password" name="password" /><br>
<input type="submit" value="提交" />
</form>
</body>
</html>

querystring 模块

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

let server=http.createServer(function (req, res){
let [url, query]=req.url.split('?');
let get=querystring.parse(query);

console.log(url, get);
});
server.listen(8080);

url 模块

1
2
3
4
5
6
7
8
9
const http=require('http');
const url=require('url');

let server=http.createServer(function (req, res){
let {pathname, query}=url.parse(req.url, true); // true 就是告诉他连 query 一块处理了吧,处理完变成一个 JSON

console.log(pathname, query);
});
server.listen(8080);

POST 请求

POST 因为比较大,可能会分几次发给服务器。接收的时候也要分段来接收。

req.on事件、req.end事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const http=require('http');
const querystring=require('querystring');

let server=http.createServer(function (req, res){
let arr=[];
req.on('data', buffer=>{
arr.push(buffer);
});

req.on('end', ()=>{
let buffer=Buffer.concat(arr); // 将 arr 中的数据拼在一起
let post=querystring.parse(buffer.toString()); // 转为字符串
console.log(post);
});
});
server.listen(8080);

同时接收 GET 和 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
const http=require('http');
const url=require('url');
const querystring=require('querystring');
const fs=require('fs');

http.createServer((req, res)=>{
let path='', get={}, post={};

if(req.method=='GET'){ // 如果是 GET 方式
let {pathname, query}=url.parse(req.url, true);
path=pathname;
get=query;
complete();
}else if(req.method=='POST'){ // 如果是 POST 方式
path=req.url;
let arr=[];

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

req.on('end', ()=>{
let buffer=Buffer.concat(arr);
post=querystring.parse(buffer.toString());
complete();
});
}

function complete(){
console.log(path, get, post);
}
}).listen(8080);

接口

接口-API:用户注册、登录

服务器:

  1. 请求文件 -> 结果
  2. 请求接口 -> 操作
1
2
3
4
5
6
7
注册接口:
/reg?username=xxx&password=xxx
=>{error: 1, msg: '为什么'}

登录接口:
/login?username=xxx&password=xxx
=>{error: 1, msg: 'xx'}

用户注册登录案例

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
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<script src="jquery.js" charset="utf-8"></script>
<script>
$(function (){
$('#btn1').click(()=>{
$.ajax({
url: '/reg',
data: {
username: $('#user').val(),
password: $('#pass').val()
},
dataType: 'json'
}).then(json=>{
if(json.error){
alert(json.msg);
}else{
alert('注册成功');
}
}, err=>{
alert('注册失败,请刷新重试');
});
});

$('#btn2').click(()=>{
$.ajax({
url: '/login',
data: {
username: $('#user').val(),
password: $('#pass').val()
},
dataType: 'json'
}).then(json=>{
if(json.error){
alert(json.msg);
}else{
alert('登录成功');
}
}, err=>{
alert('登录失败,请刷新重试');
});
});
});
</script>
</head>
<body>
用户:<input type="text" id="user" /><br>
密码:<input type="password" id="pass" /><br>
<input type="button" value="注册" id="btn1">
<input type="button" value="登录" id="btn2">
</body>
</html>
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
const http=require('http');
const url=require('url');
const querystring=require('querystring');
const fs=require('fs');

let users={};

http.createServer((req, res)=>{
let path='', get={}, post={};

if(req.method=='GET'){
let {pathname, query}=url.parse(req.url, true);

path=pathname;
get=query;
complete();
}else if(req.method=='POST'){
path=req.url;
let arr=[];
req.on('data', buffer=>{
arr.push(buffer);
});

req.on('end', ()=>{
let buffer=Buffer.concat(arr);
post=querystring.parse(buffer.toString());
complete();
});
}

function complete(){
if(path=='/reg'){
let {username, password}=get;

if(users[username]){
res.write(JSON.stringify({error: 1, msg: '此用户名已存在'}));
res.end();
}else{
users[username]=password;

res.write(JSON.stringify({error: 0, msg: ''}));
res.end();
}
}else if(path=='/login'){
let {username, password}=get;

if(!users[username]){
res.write(JSON.stringify({error: 1, msg: '找不到此用户'}));
res.end();
}else if(users[username]!=password){
res.write(JSON.stringify({error: 1, msg: '密码不对'}));
res.end();
}else{
res.write(JSON.stringify({error: 0, msg: ''}));
res.end();
}
}else{
fs.readFile(`www${path}`, (err, buffer)=>{
if(err){
res.writeHeader(404);
res.write('Not Found');
res.end();
}else{
res.write(buffer);
res.end();
}
});
}
}
}).listen(8080);