js之HTTP


HTTP

HTTP教程

教程

HTTP特点

1、简单快速:每个资源(比如图片、页面)都通过 url 来定位。这都是固定的,在http协议中,处理起来也比较简单,想访问什么资源,直接输入url即可。
2、灵活:HTTP允许传输任意类型的数据对象。
3、无连接:限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
4、无状态:每个请求都是独立的,与前面的请求和后面的请求都是没有直接联系的。协议本身并不保留之前一切的请求或 响应报文的信息。

请求报文组成部分

请求行,请求头,空行,请求体

请求报文具体部分


1、请求行:包括请求方法、请求的url、http协议及版本。
2、请求头:一大堆的键值对。
3、空行指的是:当服务器在解析请求头的时候,如果遇到了空行,则表明,后面的内容是请求体。
4、请求体:数据部分。

响应报文组成部分

状态行,响应头,空行,响应体

响应报文具体部分


1、状态行:http协议及版本、状态码及状态描述。
2、响应头
3、空行
4、响应体

HTTP方法

GET:获取资源
POST:传输资源
put:从客户端向服务器传送的数据取代指定的文档的内容。
DELETE:请求服务器删除指定的页面。
HEAD:类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头

get和post区别

1、浏览器在回退时,get不会重新请求,但是post会重新请求。
2、get请求的参数,会保留在浏览器的历史记录里,而post不会。为了防止CSRF攻击,很多公司把get统一改成了post。
3、get请求只能进行url编码,而post支持多种编码方式。
4、get请求在url中传递的参数有大小限制,基本是2kb,不同的浏览器略有不同。而post没有注意。
5、get的参数是直接暴露在url上的,相对不安全。而post是放在请求体中的。
4、get请求会被浏览器主动缓存,而post不会。

HTTP/1.x、HTTP/2和HTTP/3特性

教程

教程

HTTP/1.x缺陷

连接无法复用:tcp建立连接的3次握手和断开连接的4次挥手以及每次建立连接带来的RTT延迟时间,连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显。
1、HTTP/1.0 下个请求必须在前一个请求返回后才能发出,request-response对按序发生。显然,如果某个请求长时间没有返回,那么接下来的请求就全部阻塞了。
2、HTTP/1.1 尝试使用 pipeling 来解决,即浏览器可以一次性发出多个请求(同个域名,同一条 TCP 链接)。但 pipeling 要求返回是按序的,那么前一个请求如果很耗时(比如处理大图片),那么后面的请求即使服务器已经处理完,仍会等待前面的请求处理完才开始按序返回。所以,pipeling 只部分解决了 HOLB。
3、协议开销大: HTTP1.x在使用时,header里携带的内容过大,在一定程度上增加了传输的成本,并且每次请求header基本不怎么变化,尤其在移动端增加用户流量。
4、安全因素:HTTP1.x在传输数据时,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份,这在一定程度上无法保证数据的安全性

HTTP/2

HTTP/2 采用二进制格式传输数据,而非 HTTP 1.x 的文本格式,二进制协议解析起来更高效。 HTTP / 1 的请求和响应报文,都是由起始行,首部和实体正文(可选)组成,各部分之间以文本换行符分隔。HTTP/2 将请求和响应数据分割为更小的帧,并且它们采用二进制编码。
在 HTTP/2 中引入了多路复用的技术。同个域名只需要占用一个 TCP 连接,使用一个连接并行发送多个请求和响应,消除了因多个 TCP 连接而带来的延时和内存消耗。并行交错地发送多个请求,请求之间互不影响。并行交错地发送多个响应,响应之间互不干扰。

状态码

状态码详细教程

教程

1xx

指示信息-表示请求已接收,继续处理

2xx成功

这一类型的状态码,代表请求已成功被服务器接收、理解、并接受。

1
2
3
4
5
6
7
8
9
// 常用
200 - (成功)请求已成功,请求所希望的响应头或数据体将随此响应返回。
206 - (部分内容)客户端发送了一个带有range头的get请求,服务器返回了部分内容,比如播放视频地址的前一部分,后一部分要再次请求。
204 - (无内容)服务器成功处理了请求,但未返回任何内容。
// 不常用
201 - (已创建)请求成功且服务器已创建了新的资源。。
202 - (已接受)服务器已接受了请求,但尚未对其进行处理。
203 - (非授权信息)服务器已成功处理了请求,但返回了可能来自另一来源的信息。
205 - (重置内容)服务器成功处理了请求,但未返回任何内容。
3xx重定向

这类状态码代表需要客户端采取进一步的操作才能完成请求。
按照HTTP/1.0版规范的建议,浏览器不应自动访问超过5次的重定向。对重定向一般是由浏览器来控制重定向的次数,重定向会导致客户端不必要的资源消耗

1
2
3
4
5
6
7
8
9
10
// 常用
301 - 永久移除,所请求的页面已经转移到新的url。
302 - 临时移动,所请求的页面已经临时转移到新的url。
304 - 未修改。自从上次请求后,请求的网页未被修改过。所以服务器返回304告诉客户端已经有缓存了,不需要再从服务端拿了。
// 不常用
300 - 多重选择,被请求的资源有一系列可供选择的回馈信息。
303 - 查看其他位置,对应当前请求的响应可以在另一个URI上被找到,而且客户端应当采用GET的方式访问那个资源。
305 - 使用代理,被请求的资源必须通过指定的代理才能被访问。
306 - 临时重定向,在最新版的规范中,306状态码已经不再被使用。
307 - 临时重定向。
4xx客户端错误

这类的状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理。

1
2
3
4
5
6
7
8
9
10
// 常用
400 - 请求报文中存在语法错误。
401 - 请求未经授权, 请求需要用户验证。
403 - 请求被服务器拒绝。
404 - 资源不存在。
// 不常用
402 - 付款要求。
405 - 用来访问本页面的 HTTP 谓词不被允许(方法不被允许)
407 - 要求进行代理身份验证。
408 - 请求超时。
5xx服务器错误

这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理。

1
2
3
500 - 内部服务器错误。
502 - 错误网关,Web 服务器用作网关或代理服务器时收到了无效响应。
504 - 网关超时,服务器作为网关或代理,未及时从上游服务器接收请求。

web如何实时推送

http长连接/持久链接

1、轮询:http1.0中,客户端每隔很短的时间,都会对服务器发出请求,查看是否有新的消息,只要轮询速度足够快,例如1秒,就能给人造成交互是实时进行的印象。这种做法是无奈之举,实际上对服务器、客户端双方都造成了大量的性能浪费。
2、在HTTP1.0和HTTP1.1协议中都有对长连接的支持。其中HTTP1.0需要在request中增加”Connection: keep-alive“ header才能够支持,而HTTP1.1默认支持。长连接:客户端只请求一次,但是服务器会将继续保持连接,当再次请求时,避免了重新建立连接。
3、注意,HTTP 1.1默认进行持久连接。在一次 TCP 连接中可以完成多个 HTTP 请求,但是对每个请求仍然要单独发 header,Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。

长连接中的管线化

从前发送请求后需等待并收到响应,才能 发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求。通俗地讲,请求打包一次传输过去,响应打包一次传递回来。管线化的前提是在持久连接下。
假如当请求一个包含 10 张图片的 HTML Web 页面,与挨个连接相比,用持久连接可以让请求更快结束。 而管线化技术则比持久连接还要快。请求数越多,时间差就越明显。客户端需要请求这十个资源。以前的做法是,在同一个TCP连接里面,先发送A请求,然后等待服务器做出回应,收到后再发出B请求,以此类推,而管道机制则是允许浏览器同时发出这十个请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求。

1
2
3
4
5
6
// 长连接的默认请求是这样:
请求1 --> 响应1 -->请求2 --> 响应2 --> 请求3 --> 响应3

// 长连接中的管线化:
请求1 --> 请求2 --> 请求3 --> 响应1 --> 响应2 --> 响应3
管线化就是,我把现在的请求打包,一次性发过去,你也给我一次响应回来。
webSocket

一旦Web服务器与客户端之间建立起WebSocket协议的通信连接,之后所有的通信都依靠这个专用协议进行。通信过程中可互相发送JSON、XML、HTML或图片等任意格式的数据。由于是建立在HTTP基础上的协议,因此连接的发起方仍是客户端,而一旦确立WebSocket通信连接,不论服务器还是客户端,任意一方都可直接向对方发送报文。
特点:1、支持双向通信,实时性更强。
2、可以发送文本,也可以发送二进制数据。
3、减少通信量:只要建立起WebSocket连接,就希望一直保持连接状态。和HTTP相比,不但每次连接时的总开销减少,而且由于WebSocket的首部信息很小,通信量也相应减少了。

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
// websocket.html
<div id="clock"></div>
<script>
let clockDiv = document.getElementById('clock')
let socket = new WebSocket('ws://localhost:9999')
//当连接成功之后就会执行回调函数
socket.onopen = function() {
console.log('客户端连接成功')
//再向服务 器发送一个消息
socket.send('hello') //客户端发的消息内容 为hello
}
//绑定事件是用加属性的方式
socket.onmessage = function(event) {
clockDiv.innerHTML = event.data
console.log('收到服务器端的响应', event.data)
}
</script>
// websocket.js
let express = require('express')
let app = express()
app.use(express.static(__dirname))
//http服务器
app.listen(3000)
let WebSocketServer = require('ws').Server
//用ws模块启动一个websocket服务器,监听了9999端口
let wsServer = new WebSocketServer({ port: 9999 })
//监听客户端的连接请求 当客户端连接服务器的时候,就会触发connection事件
//socket代表一个客户端,不是所有客户端共享的,而是每个客户端都有一个socket
wsServer.on('connection', function(socket) {
//每一个socket都有一个唯一的ID属性
console.log(socket)
console.log('客户端连接成功')
//监听对方发过来的消息
socket.on('message', function(message) {
console.log('接收到客户端的消息', message)
socket.send('服务器回应:' + message)
})
})

HTTPS

教程

教程

什么是HTTPS

HTTPS是在HTTP上建立SSL加密层,并对传输数据进行加密,是HTTP协议的安全版。
作用:1、对数据进行加密,并建立一个信息安全通道,来保证传输过程中的数据安全; 2、对网站服务器进行真实身份认证。

HTTP的问题

1、通信使用明文(未经过加密的报文),内容可能被窃听。HTTP明文协议的缺陷是导致数据泄露、数据篡改、流量劫持、钓鱼攻击等安全问题的重要原因。
2、HTTP协议在请求或响应送出之后直到对方接收之前的这段时间内,即使请求或响应的内容遭到篡改,也没有办法获悉。
3、HTTP协议中的请求和响应不会对通信方进行确认。服务器只要接收到请求,不管对方是谁都会返回一个响应。

HTTPS协议的优势

数据隐私性:内容经过对称加密,每个连接生成一个唯一的加密密钥
数据完整性:内容传输经过完整性校验
身份认证:第三方无法伪造服务端(客户端)身份