# 深入探索网络请求

# 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
<!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

# 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

# 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
  • 服务端
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
Last Updated: 6/4/2022, 9:31:26 PM
강남역 4번 출구
Plastic / Fallin` Dild