# 深入探索网络请求
# HTTP/0.9、HTTP/1.0、HTTP/1.1、HTTP/2.0的区别
# HTTP/0.9
- 只允许客户端发送GET这一种请求
- 不支持请求头
- HTTP/0.9协议只支持一种内容,即纯文本
- 无法插入图片。
# HTTP/1.0
- 请求与响应支持头部。
- 响应对象以一个响应状态码开始。
- 响应对象不只限于超文本。
- 开始支持客户端通过POST方法向web服务器提交数据,支持GET、HEAD、POST方法。
- 支持长连接(但默认还是使用短连接)、缓存机制以及身份认证。
# HTTP/2.0
- 帧:客户端与服务器通过交换帧来通信,帧是基于这个新协议通信的最小单位。 消息:指逻辑上的HTTP消息,比如请求、响应等,由一或多个帧组成。
- 流:流是连接中的一个虚拟信道,可以承载双向的消息;每个流都有一个唯一的整数标识符(1,2…N)。
- 多路复用
- 头部压缩 HTTP/1.1的首部带有大量信息,而且每次都要重复发送。HTTP/2.0要求通讯双方各自缓存一份首部字段表,从而避免了重复传输。
- 请求优先级 浏览器可以在发现资源时立即分派请求,指定每个流的优先级,让服务器决定最优的响应次序。这样请求就不必排队了,既节省了时间,也最大限度地利用了每个连接。
# 跨域网络访问
- 跨域写操作一般被允许: 链接,重定向,表单提交
- 跨域资源嵌入: script, img, link, video, object,embed, iframe
# 网络跨域解决方案
# jsonp
app.get('/jsonp_request', (_req, res) => {
const params = urlLib.parse(_req.url, true);
if (params.query && params.query.callback) {
var str = params.query.callback + '(' + JSON.stringify({ test: "服务端数据" }) + ')';
console.log(str, 'str')
res.send(str);
} else {
res.send('world')
}
console.log(params.query.callback);
})
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
function jsonpCallback(data) {
alert('收到数据了,快来控制台看看');
console.log("收到的数据:",data);
}
</script>
<script src="http://127.0.0.1:3000/jsonp_request?callback=jsonpCallback"></script>
</head>
<body>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# cors
//设置跨域访问
app.use(function (req: any, res: any, next: any) {
const origin = req.headers.origin as string;
if (whitList.includes(origin)) {
//设置允许跨域的域名,*代表允许任意域名跨域
res.header("Access-Control-Allow-Origin", "*");
//允许携带凭证
res.header("Access-Control-Allow-Credentials", 'true');
//允许的header类型
res.header("Access-Control-Allow-Headers", ["X-PINGOTHER", "content-type", "Origin", "Accept"]);
//允许浏览器获取的请求头
res.header("Access-Control-Expose-Headers", "test");
//跨域允许的请求方式
res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
//预检结果保存时间 1小时
res.header("Access-Control-Max-Age", `${5}`);
if (req.method.toLowerCase() == 'options') {
res.send(204); //让options尝试请求快速结束
return;
}
}
next();
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# websocket
- 客户端
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>聊天室</title>
</head>
<style>
.txt{
font-size: 30px;
}
.inputBtn{
font-size: 40px;
}
</style>
<body>
<form onsubmit="return false;">
<h1>慕课聊天室:</h1>
<textarea id="repText" class="txt" style="width: 800px; height: 600px;"></textarea>
<br>
<input class="inputBtn" type="text" id="myInput" name="message" style="width: 300px" value="Hello world">
<input class="inputBtn" type="button" id="mySend" value="发送消息" onclick="send(this.form.message.value)">
</form>
<script type="text/javascript">
let socket;
const repTextEl=document.getElementById('repText');
if (window.WebSocket) {
socket = new WebSocket("ws://127.0.0.1:18000");
socket.onmessage = function (event) {
repTextEl.value = repTextEl.value + '\n' + event.data
};
socket.onopen = function (event) {
repTextEl.value = "webSocket已链接";
};
socket.onclose = function (event) {
repTextEl.value = repTextEl.value + "连接被关闭";
};
} else {
console.log("浏览器不支持webSocket")
}
function send(message) {
if (!window.WebSocket) {
return;
}
if (socket.readyState == WebSocket.OPEN) {
socket.send(message);
} else {
console.log("webSocket还没有开启")
}
}
</script>
</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
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
- 服务端
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 18000 });
server.on('open', function open() {
console.log('connected');
});
server.on('close', function close() {
console.log('disconnected');
});
server.on('connection', function connection(ws, req) {
// 发送欢迎信息给客户端
ws.send("服务器欢迎你链接");
ws.on('message', function incoming(message) {
// 广播消息给所有客户端
server.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send( "服务器收到客户端消息 -> " + message);
}
});
});
});
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
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
← 前端发布脚手架
