目录
- HTTP1.x、HTTP2、HTTP3
- HTTP1.0 和HTTP1.1的一些区别
- HTTP2.0和HTTP1.X相比的新特性
- 为什么 HTTP1.1 不能实现多路复用
- 多路复用和 keep alive区别
- HTTPS
- HTTP和HTTPS的区别
- HTTPS握手过程
- HTTPS通过什么保证是安全的
- 三次握手,四次挥手,为什么是三次和四次
- HTTP 的请求方法有哪些?GET和POST区别?
- webSocket
- Ajax, Fetch, Axios
http1.x、http2、http3
http1.0 和HTTP1.1的一些区别
- 长连接
- 在HTTP1.1中默认开启Connection: keep-alive,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟
- 缓存处理
- http1.0 主要使用header中的Exprires, If-Modified-Since来做为缓存判断的标准
- HTTP1.1 Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
- 带宽优化及网络连接的使用
- HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content)
- Host头处理
- 在HTTP/1.0中认为每台服务器都有唯一的IP地址,但随着虚拟主机技术的发展,多个主机共享一个IP地址愈发普遍,HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会400错误
HTTP2.0和HTTP1.X相比的新特性
HTTP1.x存在的问题:
- TCP连接数限制
对于同一个域名,浏览器最多只能同时创建6 ~ 8个TCP链接。为了解决数量的限制,出现 域名分片技术。 - 队头阻塞(Head-Of-Line Blocking)
当HTTP开启长连接时,共用一个TCP连接,同一时刻只能处理一个请求,浏览器按 FIFO 原则处理请求,如果上一个响应没返回,后续请求 - 响应都会受阻。 - header内容多,并且每次请求 Header不会变化太多,没有相应的压缩传输优化方案
- 为了尽可能减少请求数,需要做合并文件、雪碧图、资源内联等优化工作,但是这无疑造成了单个请求内容变大延迟变高的问题,且内嵌的资源不能有效地使用缓存机制
- 明文传输不安全
HTTP2
二进制传输
HTTP/2传输数据量的大幅减少,主要有两个原因:以二进制方式传输和Header 压缩, HTTP/2 采用二进制格式传输数据,而非HTTP/1.x 里纯文本形式的报文 ,二进制协议解析起来更高效
HTTP/2 将请求和响应数据分割为更小的帧,并且它们采用二进制编码。帧是数据传输的最小单位,以二进制传输代替原本的明文传输,原本的报文消息被划分为更小的数据帧。多路复用
在一个TCP连接上,我们可以向对方不断发送帧,每帧的 stream identifier 标明这一帧属于哪个流,然后在对方接收时,根据 stream identifier 拼接每个流的所有帧组成一整块数据。 把 HTTP/1.1 每个请求都当作一个流,那么多个请求变成多个流,请求响应数据分成多个帧,不同流中的帧交错地发送给对方,这就是 HTTP/2 中的多路复用。header压缩
使用 HPACK 算法来压缩首部内容服务端推送
浏览器发送一个请求,服务器主动向浏览器推送与这个请求相关的资源,这样浏览器就不用发起后续请求。比如,在浏览器刚请求HTML的时候就提前把可能会用到的JS、CSS文件发给客户端,减少等待的延迟,这被称为"服务器推送"( Server Push,也叫 Cache push)
HTTP/1 的几种优化可以弃用:
合并文件、内联资源、雪碧图、域名分片对于 HTTP/2 来说是不必要的,使用 h2 尽可能将资源细粒化,文件分解地尽可能散,不用担心请求数多
为什么 HTTP1.1 不能实现多路复用
HTTP/1.1 不是二进制传输,而是通过文本进行传输。由于没有流的概念,在使用并行传输(多路复用)传递数据时,接收端在接收到响应后,并不能区分多个响应分别对应的请求,所以无法将多个响应的结果重新进行组装,也就实现不了多路复用。
多路复用和 keep alive区别
[图片上传失败...(image-65a055-1587046342922)]
- 队头阻塞(Head-of-Line Blocking),HTTP1.X虽然可以采用Keep alive来解决复用TCP的问题,但是还是无法解决请求阻塞;
- 所谓请求阻塞意思就是一条 TCP 的connection在同一时间只允许一个请求经过,这样假如后续请求想要复用这个链接就必须等到前一个完成才行,正如上图左边表示的。
- 之所以有这个问题就是因为HTTP1.x需要每条请求都是可以识别,按顺序发送,否则serve就无法判断该响应哪个具体的请求。
- HTTP2采用多路复用是指,在同一个域名下,开启一个TCP的connection,每个请求以stream的方式传输,每个stream有唯一的标识,connection一旦建立,后续的请求都可以复用这个connection并且可以同时发送,server端可以根据stream的唯一标识来响应对应的请求。
http3
HTTP/2 的缺点
尽管HTTP/2解决了很多1.1的问题,但HTTP/2仍然存在一些缺陷,这些缺陷并不是来自于HTTP/2协议本身,而是来源于底层的TCP协议,我们知道TCP链接是可靠的连接,如果出现了丢包,那么整个连接都要等待重传,HTTP/1.1可以同时使用6个TCP连接,一个阻塞另外五个还能工作,但HTTP/2只有一个TCP连接,阻塞的问题便被放大了。
http3
由于TCP协议已经被广泛使用,我们很难直接修改TCP协议,基于此,HTTP/3选择了一个折衷的方法——UDP协议,HTTP/2在UDP的基础上实现多路复用、0-RTT、TLS加密、流量控制、丢包重传等功能。
https
HTTP和HTTPS的区别
- HTTP 使用80端口,HTTPS使用443端口
- HTTPS需要申请证书
- HTTP是超文本传输协议,是明文传输;HTTPS是经过SSL加密的协议,传输更加安全
- HTTPS比HTTP慢
- 通信慢:HTTPS和HTTP相比,除去TCP连接、发送HTTP请求-响应以外,还必须进行SSL通信。
- 加密处理:加密和解密运算处理耗时
HTTPS握手过程
- 客户端使用HTTPS的URL访问Web服务器,要求与服务器建立SSL连接
- web服务器收到客户端请求后, 会将网站的证书(包含公钥)传送一份给客户端
- 客户端收到网站证书后会检查证书的颁发机构以及过期时间, 如果没有问题就随机产生一个密钥
- 客户端利用公钥将会话密钥加密, 并传送给服务端, 服务端利用自己的私钥解密出会话密钥
- 之后服务器与客户端使用密钥加密传输
HTTPS通过什么保证是安全的
HTTP + 加密 + 认证 + 完整性保护 = HTTPS
加密:
- 共享密钥加密(对称加密):加密和解密使用同一个密钥
- 存在问题:如何安全的发送密钥?以发送密钥就有被窃听的风险,但不发送,对方就不能解密。
- 公开密钥加密(非对称加密):使用一对非对称的密钥。一把叫做私有密钥,另一把叫做公开密钥加密。
- 可以解决共享密钥加密的问题:发送密文的一方使用对方的公开密钥进行加密处理,对方收到被加密的信息后,再使用自己的私有密钥进行解密。利用这种方式,不需要发送用来解密私有密钥,也不必担心密钥被攻击者窃听而盗走。
- HTTPS采用混合加密机制
- HTTPS采用 共享密钥加密 和 公开密钥加密 两者并用的混合加密机制,若密钥能够实现安全交换,那么可能会考虑仅使用非对称加密来通信。但是对称加密和非对称加密相比,其处理速度要慢。
- 所以应充分利用两者各自的优势,将多种方法组合起来用于通信。在交换密钥环节使用公开密钥加密方式,之后建立通信交换报文阶段则使用共享密钥加密方式
认证:证明公开密钥正确性的证书
使用数字证书认证机构(CA)和其他相关机关颁发的公开密钥证书
三次握手,四次挥手,为什么是三次和四次
三次握手
- 发送端首先发送一个带SYN标志的数据包给对方
- 接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息
- 最后,发送端再回传一个带ACK标志的数据包,代表“握手”结束。
若在握手过程中某个阶段莫名中断,TCP协议会再次以相同的顺序发送相同的数据包。
握手为什么是三次?
三次握手其实就是建立一个TCP连接时,需要客户端和服务器总共发出3个包,进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常。指定自己的初始化序列号为后面的可靠性传送做准备。
第一次握手:客户端发送网络包,服务端收到了。
这样服务端就能得出结论:客户端的发送能力。服务端的接收能力是正常的。
第二次握手:服务端发包,客户端收到了。
这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收。发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
第三次握手:客户端发包,服务端收到了。
这样服务端就能得出结论:客户端的接收。发送能力正常,服务器自己的发送、接收能力也正常。
试想如果是用两次握手,则会出现下面这种情况:
如客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接,客户端共发出了两个连接请求报文段,其中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,此时服务端误认为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,不采用三次握手,只要服务端发出确认,就建立新的连接了,此时客户端忽略服务端发来的确认,也不发送数据,则服务端一致等待客户端发送数据,浪费资源。
四次挥手
- 第一次挥手:主动关闭方发送一个
FIN
,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不 会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack
确认报文,主动关闭方依然会重发这些数据),但是,此时主动关闭方还可 以接受数据。 - 第二次挥手:被动关闭方收到
FIN
包后,发送一个ACK
给对方,确认序号为收到序号+1(与SYN
相同,一个FIN
占用一个序号)。 - 第三次挥手:被动关闭方发送一个
FIN
,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。 - 第四次挥手:主动关闭方收到
FIN
后,发送一个ACK
给被动关闭方,确认序号为收到序号+1
,至此,完成四次挥手。
挥手为什么是四次?
因为当服务端收到客户端的SYN连接请求报文后,可以直接发送 SYN + ACK 报文。其中 ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,“你发的FIN报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四次挥手。
HTTP 的请求方法有哪些?GET和POST区别?
HTTP 的请求方法
- GET:获取资源
- POST:传输实体主体
- PUT:传输文件
- HEAD:获得报文首部
- DELETE:删除文件
- OPTIONS:询问支持的方法
- TRACE: 追踪路径TRACE方法是让Web服务器端将之前的请求通信环回给客户端的方法。
- 发送请求时,在Max-Forwards首部字段中填入数值,每经过一个服务器端就将该数字减1,当数值刚好减到0时,就停止继续传输,最后接收到请求的服务器端则返回状态码200OK的响应。
- CONNECT: 要求用隧道协议链接代理
GET和POST区别
- 缓存: GET 请求会被浏览器主动缓存下来,留下历史记录,而 POST 默认不会
- 编码: GET 只能进行 URL 编码,只能接收 ASCII 字符,而 POST 没有限制。
- 参数: GET 一般放在 URL 中,因此不安全,POST 放在请求体中,更适合传输敏感信息。
- 幂等: GET是幂等的,而POST不是。(幂等表示执行相同的操作,结果也是相同的)
- TCP: GET请求会把浏览器会把http header和data一次性发出去,而POST会分成两个TCP数据包,首先发Header部分,如果服务器响应100(continue), 然后发 body 部分。(火狐浏览器除外,它的 POST 请求只发一个 TCP 包)
HTTP状态码
1xx (信息性状态码) 接受的请求正在处理
-
2xx 成功 请求正常处理完毕
- 200 OK 客户端发来的请求在服务器端被正常处理了
- 204 No Content 服务器接收的请求已成功处理,但是返回的响应报文中不含实体的主体部分,另外,也不允许返回任何实体的主体
一般在只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。 - 206 Partial Content 客户端进行了范围请求,而服务器成功执行了这部分的Get请求,响应报文中包含Content-Range指定范围的实体内容
-
3xx 重定向 需要进行附加操作已完成请求
- 301 Moved Permanently 永久性重定向
- 302 Found 临时性重定向
- 303 See Other 表示由于请求对应的资源错在着另一个URI,应用GET方法定性获取请求的资源
- 304 Not Modified 表示客户端发送附带条件的请求时,服务器允许请求访问资源,但未满足条件的情况下
- 附带条件的请求是指采用GET方法的请求报文中包含If-Match,If-Modified-Since, If-None-Match,If-Range,If-Unmodified-Since中任一的首部
-
4xx 客户端错误 服务器无法处理请求
- 400 Bad Request 请求报文中存在语法错误
- 401 Unauthorized 表示发送的请求需要有通过HTTP认证
- 403 Forbidden 对请求资源的访问被服务器拒绝了
- 404 Not Found 服务器无法找到请求的资源
-
5xx 服务器错误 服务器处理请求错误
- 500 Internal Server Error 服务器在执行时发生了错误
- 503 Service Unavailable 表明服务器暂时处于超负载或正在进行停机维护
WebSocket
HTTP协议通信只能由客户端发送,实现想消息通知的这种,我们只能使用“轮询”:每隔一段时间,就发出一个后端请求,询问有没有新的消息更新。
WebSocket 和 HTTP 一样,同属于应用层协议。它最重要的用途是实现了客户端与服务端之间的全双工通信,当服务端数据变化时,可以第一时间通知到客户端。
除此之外,它与http协议不同的地方还有:
- http只能由客户端发起,而webSocket是双向的。
- webSocket传输的数据包相对于http而言很小,很适合移动端使用
- 没有同源限制,可以跨域共享资源
Ajax, Fetch, Axios
ajax
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText) // 从服务器获取数据
}
}
xhr.send();
- 创建XML
- 发送请求
- 通过回调获取响应信息
Fetch
Fetch的API是基于Promise设计的。fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象
fetch(url)
.then(response => {
if (response.ok) {
// fetch()请求返回的response是Stream对象,因此我们调用response.json时由于异步读取流对象所以返回的是一个Promise对象
return response.json();
}
})
.then(data => console.log(data))
.catch(err => console.log(err))
axios
axios是对原生 XHR的封装,基于Promise的http库,适用于浏览器和node.js。有以下几大特性:
- 浏览器端发起XMLHttpRequests请求
- node端发起http请求
- 支持Promsise API
- 提供了并发请求的接口
- 支持拦截请求和响应
- 转换请求和响应数据
- 取消请求
- 自动转化json数据
更多使用可以直接查阅 axios文档