TCP和UDP
UDP 和 TCP 协议的区别?有什么应用场景
UDP(User Datagram Protocol,用户数据报协议)
- 无连接协议:UDP 是一种无连接协议,发送数据前不需要建立连接。
- 不提供错误恢复:UDP 不提供错误恢复机制,如果数据包丢失,不会进行重传。
- 传输速度快:由于没有错误检查和连接建立的过程,UDP 传输速度更快,延迟更低。
- 应用场景:适用于对速度要求高且允许偶尔数据丢失的应用, 如直播流媒体、在线游戏和语音通话(VoIP)
TCP(Transmission Control Protocol,传输控制协议) - 面向连接协议:TCP 在发送数据前需要建立连接,确保通信的可靠性。
- 提供错误恢复:TCP 提供错误检查,确保数据按顺序且无误地传输。
- 传输速度较慢:由于需要建立连接和进行错误检查,TCP 的传输速度相对较慢。
- 应用场景:适用于对数据完整性和顺序有严格要求的应用,如网页浏览、电子邮件和文件传输。
TCP三次握手和四次挥手
三次握手
确定双方的接收和发送能力是正常的
第一次握手
客户端向服务端发送建立连接请求,客户端进入SYN-SEND状态,syn就是报文,send就是发送
第二次握手
服务端接收到建立连接请求后,向客户端发送一个应答SYN+ACK,服务端进入SYN-RECEIVED状态,received就是接收到了
第三次握手
客户端接收到应答后,发送ACK确认接收到应答,双方进入ESTABLISHED状态
为什么不是两次握手?
防止已经失效的请求报文,突然又传到服务器引起错误。
如果是两次握手:假如第一次的请求报文因为某些原因没有发送到服务端,后面客户端重新发送请求连接,这次成功了,双方建立连接了,但是第一个SYN包又突然好了,发送到服务端。服务端就会认为是客户端又重新发起了一个连接。服务端以为是两个连接,客户端以为是一个连接。状态不一致。如果是三次握手,服务端没有收到最后一个ack包,就不会认为是成功建立连接。
三次握手的目的:为了能在不可靠的信道上 建立起可靠的连接。
TCP可靠:解决丢包问题和乱序问题
一包数据可能会被拆分成多个部分,如何处理丢包问题和乱序问题(不区分是客户端还是服务端,全双工通信)
有发送缓冲区,每次都取一部分数据
发送报文:序列号+数据长度+数据内容
回复确认:ack=序列号+长度=下一包的起始序列
切割发送 根据序列号和长度重组数据,丢失重传
四次挥手
TCP四次挥手是TCP连接终止的过程,用于确保连接双方都能完成数据传输并安全地关闭连接,以下是其简要过程:
- 第一次挥手:主动关闭方(例如客户端)发送一个FIN(Finish)报文段,用来表示自己已经没有数据要发送了,但仍然可以接收数据。此时,主动关闭方进入FIN_WAIT_1状态。
- 第二次挥手:被动关闭方(例如服务器)收到FIN报文段后,会发送一个ACK(Acknowledgment)报文段作为应答,表示已经收到了关闭请求,并且确认序号为收到的FIN报文段的序号加1。此时,被动关闭方进入CLOSE_WAIT状态,而主动关闭方收到ACK后进入FIN_WAIT_2状态
- 第三次挥手:当被动关闭方也没有数据要发送时,它会发送一个FIN报文段给主动关闭方,请求关闭连接。此时,被动关闭方进入LAST_ACK状态。
- 第四次挥手:主动关闭方收到被动关闭方的FIN报文段后,会发送一个ACK报文段作为应答,并将确认序号设置为收到的FIN报文段的序号加1。然后,主动关闭方进入TIME_WAIT状态。在经过一段时间(通常是2倍的MSL,即最长报文段寿命)后,主动关闭方会进入CLOSED状态,彻底关闭连接。被动关闭方收到ACK报文段后,会立即进入CLOSED状态。
通过四次挥手,TCP连接双方能够有序地释放连接资源,确保数据的可靠传输和连接的正常终止。
客户端向服务端发送断开连接请求
服务端收到断开连接请求后,告诉应用层去释放 tcp 连接
服务端向客户端发送最后一个数据包 FINBIT ,服务端进入 LAST-ACK 状态
客户端收到服务端的断开连接请求后,向服务端确认应答
为什么不是三次挥手
四次挥手是因为服务端 有 未发送完的数据
所以需要服务端 连续发送2次
同时客户端的最后等待也是为了确认 服务端收到请求
如果过了等待时间,就认为服务端已经关闭,没有关闭就会有ack
为什么是四次挥手
服务端在收到客户端断开连接Fin报文后,并不会立即关闭连接,而是先发送一个ACK包先告诉客户端收到关闭连接的请求,只有当服务器的所有报文发送完毕之后,才发送FIN报文断开连接,因此需要四次挥手
在状态方面
三次握手的客户端和服务端都是由原来的 closed 变为 established
四次挥手的客户端和服务端都是由原来的 established 变为 closed。
HTTP协议
应用层协议,客户端和服务器端 之间传输数据的协议。传输各种资源文件
HTTP⾸部字段?
Accept: 允许的媒体类型
Connection: 连接选项,例如是否允许代理
Host: 客户端发送请求时,指定服务器的域名
If-None-Match: 判断请求实体的Etag是否包含在If-None-Match中,如果包含,则返回304,
使⽤缓存
If-Modified-Since: 判断修改时间是否⼀致,如果⼀致,使⽤缓存
If-Match: 与If-None-Match相反
If-Unmodified-Since: 与If-Modified-Since相反
Referer: 这个请求发起的源头
Cache-Control: 缓存策略,如max-age:100
Connection: 连接选项,例如是否允许代理
Content-Encoding: 返回内容的编码,如gzip
Etag: entity tag,实体标签,给每个实体⽣成⼀个单独的值,⽤于客户端缓存,与If-None-M
atch配合使⽤
Expires: 设置缓存过期时间,Cache-Control也会相应变化
Last-Modified: 最近修改时间,⽤于客户端缓存,与If-Modified-Since配合使⽤
Pragma: 似乎和Cache-Control差不多,⽤于旧的浏览器
Server: 服务器信息
一次http请求过程
1.DNS 解析出 IP 地址
2.建立 TCP 连接
3.客户端发出 HTTP 请求(请求报文)
4.服务端处理 HTTP 请求()
5.发送 HTTP 响应 (响应报文)
服务端关闭连接
剩下的是客户端的处理响应
HTTP状态码
- 1xx 信息性状态码
- 这类状态码表示接收的请求正在处理中。临时响应,服务器收到请求,需要请求者继续执行操作 |
- 2xx 成功状态码
- 这类状态码表示请求已被成功接收、理解,并被接受。
- 3xx 重定向状态码
- 这类状态码表示需要客户端采取进一步的动作才能完成请求。
- 4xx 客户端错误状态码
- 这类状态码表示请求包含语法错误或无法完成请求。
- 404请求资源不存在
- 403 协商缓存
- 5** 服务端错误
**HTTP 状态码** | **英文名称** | **中文描述** |
| ------------ | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| 100 | Continue | 客户端征询服务器状况,如果服务器同意可以返回 100,同时客户端可以继续请求。常见的案例是在上传大文件的情况下,客户端先上传请求头部,交给服务端校验权限、文件名称合法性,如果符合,返回 100,客户端再传输剩下的数据。否则返回 400 之类的错误,直接终止服务 |
| 101 | Switching Protocol | 服务器应客户端升级协议的请求对协议进行切换,例如上面提到的 WebSocket |
| 200 | OK | 请求成功 |
| 301 | Permanently Moved | 该资源已经永久性转移 |
| 302 | Temporarily Moved | 该资源暂时性转移 |
| 304 | Not Modified | 所请求的资源未修改,和缓存机制有关 |
| 400 | Bad Request | 客户端请求的语法错误,服务器无法理解 |
| 401 | Unauthorized | 请求要求用户的身份认证 |
| 403 | Forbidden | 服务器理解请求客户端的请求,但是拒绝执行此请求 |
| 404 | Not Found | 服务器无法根据客户端的请求找到资源 |
| 405 | Method Not Allowed | 客户端请求中的方法被禁止 |
| 500 | Internal Server Error | 服务器内部错误,无法完成请求 |
| 501 | Not Implemented | 此请求方法不被服务器支持且无法被处理。
HTTP 报⽂组成部分
http报⽂:由请求报⽂和响应报⽂组成
请求报⽂:由请求⾏、请求头、空⾏、请求体四部分组成
响应报⽂:由状态⾏、响应头、空⾏、响应体四部分组成
常⻅的HTTP请求⽅法
GET: 向服务器获取数据;
POST:将实体提交到指定的资源,通常会造成服务器资源的修改;
PUT:上传⽂件,更新数据;
DELETE:删除服务器上的对象;
HEAD:获取报⽂⾸部,与GET相⽐,不返回报⽂主体部分;
OPTIONS:获取当前URL所⽀持的⽅法;
CONNECT:要求在与代理服务器通信时建⽴隧道,使⽤隧道进⾏TCP通信;
TRACE: 回显服务器收到的请求,主要⽤于测试或诊断。
GET方法和POST方法有何区别
keep-alive
HTTP 和 HTTPS 协议的区别
- HTTP 是超⽂本传输协议,信息是明⽂传输,存在安全⻛险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP ⽹络层之间加⼊了 SSL/TLS 安全协议,使得报⽂能够加密传输。
- HTTP 连接建⽴相对简单, TCP 三次握⼿之后便可进⾏ HTTP 的报⽂传输。⽽ HTTPS 在TCP 三次握⼿之后,还需进⾏ SSL/TLS 的握⼿过程,才可进⼊加密报⽂传输。
- 两者的默认端⼝不⼀样,HTTP 默认端⼝号是 80,HTTPS 默认端⼝号是 443。
- HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。
- https 通过混合加密(对称⾮对称)保证信息的机密性、摘要算法保证数据的完整性,将服务器的公钥放⼊数字证书中,防⽌冒充。
HTTPS 采⽤的是对称加密和⾮对称加密结合的「混合加密」⽅式:
- 在通信建⽴前采⽤⾮对称加密的⽅式交换「会话秘钥」,后续就不再使⽤⾮对称加密。
- 在通信过程中全部使⽤对称加密的「会话秘钥」的⽅式加密明⽂数据。
- 采⽤「混合加密」的⽅式的原因:
- 对称加密只使⽤⼀个密钥,运算速度快,密钥必须保密,⽆法做到安全的密钥交换。
- ⾮对称加密使⽤两个密钥:公钥和私钥,公钥可以任意分发⽽私钥保密,解决了密钥交换问题但速度慢。
对称加密和非对称加密
对称加密:使用相同的密钥加密解密
- 优点:计算量小,加密速度快,加密效率高
- 缺点:需要双方都保存密钥,如果一方的密钥 泄漏了,那么加密信息就不安全了
- 使用场景:本地数据加密,网络传输,https通信
- 常见算法:AES DES 非对称加密:通信的双方使用不同的密钥加密解密,使用密钥对 公钥和私钥
- 优点:安全性更好;
- 缺点:加密解密时间长,速度慢,只适合对少量数据进行加密
- 使用场景:https,ca数字证书,登录
- 常见算法:RSA DSA ECC
⾮对称加密和对称加密的过程
- 密钥对⽣成:⾸先,服务器需要⽣成⼀个密钥对,包括公钥和私钥。公钥是公开的,⽤于加密数据,⽽私钥必须保密,⽤于解密数据。
- 证书申请:服务器通常会向⼀个可信任的证书颁发机构(CA,Certificate Authority)申请数字证书。这个证书包含了服务器的公钥以及与该公钥相关的信息,如服务器的域名和CA的数字签名。
- 证书颁发:CA对服务器的身份进⾏验证,并签发数字证书。证书包含了CA的数字签名,⽤于验证证书的真实性。
- 客户端连接:当客户端(例如浏览器)尝试连接到服务器时,服务器会将其证书发送给客户端。
- 客户端验证:客户端接收到服务器的证书后,会检查证书的有效性。它会验证证书是否由已知和信任的CA签发,并检查证书是否已过期。如果证书有效,客户端将继续通信。
- 密钥协商:⼀旦证书验证通过,客户端⽣成⼀个随机的对称密钥,称为会话密钥。然后,客户端使⽤服务器的公钥对该会话密钥进⾏加密,并将其发送给服务器。
- 服务器解密:服务器使⽤其私钥解密客户端发送的加密的会话密钥。
- 加密通信:⼀旦双⽅都具有相同的会话密钥,他们可以使⽤对称加密算法来加密和解密实际的数据传输。这个会话密钥只在当前会话中使⽤,并且不会⻓期存储,从⽽提供了额外的安全性。
数字证书
如何证明公钥是可靠的(CA权威机构认证颁发数字证书,网站需要申请数字证书)
颁发过程
- 用户首先产生自己的密钥对,并将公共密钥及部分个人身份信息传送给认证中心。
- 认证中心将发给用户一个数字证书,该证书内包含用户的个人信息和他的公钥信息,同时还附有认证中心的签名信息(根证书私钥签名)。
数字签名
证书不被篡改 =>数字签名 签名就是在信息的后面再加上一段内容,可以证明信息没有被修改过。
一般是对信息做一个 hash 计算得到一个 hash 值,注意,这个过程是不可逆的,也就是说无法通过 hash 值得出原来的信息内容。
在把信息发送出去时,把这个 hash 值加密后做为一个签名和信息一起发出去。
接收方在收到信息后,会重新计算信息的 hash 值,并和信息所附带的 hash 值(解密后)进行对比,如果一致,就说明信息的内容没有被修改过,。
可以根据证书的所有的内容,生成一个唯一标识!!一旦内容如果被修改了,再次生成唯一标识时,和之前生成的唯一标识就不一样!检测是否被修改!
验证
浏览器/操作系统默认内置了 CA 的根证书。根证书包含了这个 CA 的公钥。 请求时,网站就会将数字证书给到浏览器,浏览器默认就会检测证书的可靠性!
- (1)是否是权威机构发布的!
- (2)看证书中记录的地址 和 当前访问的网站的地址,是否一致,只有一致,才可靠!
- (3)数字签名的计算,判断证书是否被修改过
- (4)看证书是否过期- 证书可在其过期前被吊销。较新的浏览器如 Chrome、 Firefox、Opera 和 Internet Explorer 都实现了在线证书状态协议(OCSP)以排除这种情形:浏览器将网站提供的证书的序列号通过 OCSP 发送给证书颁发机构,后者会告诉浏览器证书是否还是有效的。
TLS握手过程
- ⾸先由客户端向服务器端发送使⽤的协议的版本号、⼀个随机数和可以使⽤的加密⽅法。
- 服务器端收到后,确认加密的⽅法,也向客户端发送⼀个随机数和⾃⼰的数字证书。
- 客户端收到后,⾸先检查数字证书是否有效,如果有效,则再⽣成⼀个随机数,并使⽤证书中的公钥对随机数加密,然后发送给服务器端,并且还会提供⼀个前⾯所有内容的 hash 值供服务器端检验。
- 服务器端接收后,使⽤⾃⼰的私钥对数据解密,同时向客户端发送⼀个前⾯所有内容的 hash 值供客户端检验。这个时候双⽅都有了三个随机数,按照之前所约定的加密⽅法,使⽤这三个随机数⽣成⼀把秘钥,以后双⽅通信前,就使⽤这个秘钥对数据进⾏加密后再传输。
TLS(Transport Layer Security)握手过程如下: TLS四次握手的流程
第一次握手:客户端告诉服务端,它支持什么样的加密协议版本,比如TLS1.2,使用什么样的加密套件,比如最常见的RSA,同时还给出一个客户端随机数 第二次握手:服务端告诉客户端确定的加密方式等信息,比如就是TLS1.2,RSA,服务器证书以及服务器随机数。 第三次握手:此时客户端从第二次握手的服务器证书里取出服务器公钥,同时再生成第三个随机数预主秘钥,用公钥加密预主秘钥(pre_master_key)。此时客户端这边已经拥有三个随机数,用这三个随机数进行计算,得到一个会话秘钥,同时把迄今为止的通信数据内容生成一个摘要,也叫finished报文,用会话秘钥加密一下发给服务器做校验。 第四次握手:服务端使用服务器私钥进行解密,得到预主秘钥,集齐三个随机数,和客户端一样,使用同样的算法获得一个会话秘钥,同样把迄今为止的通信内容生成一个摘要,也就是finished报文,发给客户端做校验。 四次握手之后,两端后续就会用这个会话秘钥进行对称加密通信。
通过TLS握手,客户端和服务器之间建立了安全的连接,后续的通信数据将使用协商好的加密算法和会话密钥进行加密传输,确保数据的机密性和完整性。
HTTP版本
HTTP 1.1
- 只允许客户端主动发起请求
- 一个请求只能对应一个响应
- 同一个会话的多次请求中,头信息会被重复传输,增加传输开销
- 如果使用 Cookie,增加的开销有时会达到上千字节
- 引入持久连接( keep-alive ):一个 TCP 连接可传输多个 HTTP 请求
- 默认开启 keep-alive,通常限制 6-8 个并发连接
- 存在队头阻塞问题:前面的请求阻塞会影响后续请求
在 HTTP/1.1 中,一个连接一次只能发送一个请求,当一个请求因为网络拥塞、服务器繁忙等原因被阻塞时,后续的请求即使已经准备好也无法发送,只能在队列中等待,这会导致整个连接的性能下降,用户体验变差。
HTTP 2.0
- 一个域名只使用一个 TCP 长连接
- 引入二进制分帧层,实现多路复用
- 可对请求设置优先级
- 引入 HTTPS(HTTP + TLS) 加密
HTTP 2.0 优点
HTTP 1.1 和 HTTP 2.0 的区别
- HTTP/2 是⼀个⼆进制协议。在 HTTP/1.1 版中,报⽂的头信息必须是⽂本(ASCII 编码),数据体可以是⽂本,也可以是⼆进制。HTTP/2 则是⼀个彻底的⼆进制协议,头信息和数据体都是⼆进制,并且统称为"帧",可以分为头信息帧和数据帧。 帧的概念是它实现多路复⽤的基础。
- 多路复⽤:HTTP/2 实现了多路复⽤,HTTP/2 仍然复⽤ TCP 连接,但是在⼀个连接⾥,客户端和服务器都可以同时发送多个请求或回应,⽽且不⽤按照顺序⼀⼀发送,这样就避免了"队头堵塞"。
- 数据流:HTTP/2 使⽤了数据流的概念,因为 HTTP/2 的数据包是不按顺序发送的,同⼀个连接⾥⾯连续的数据包,可能属于不同的请求。因此,必须要对数据包做标记,指出它属于哪个请求。HTTP/2 将每个请求或回应的所有数据包,称为⼀个数据流。每个数据流都有⼀个独⼀⽆⼆的编号。数据包发送时,都必须标记数据流 ID ,⽤来区分它属于哪个数据流。
- 头信息压缩:HTTP/2 实现了头信息压缩,由于 HTTP 1.1 协议不带状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,⽐如 Cookie 和 User Agent ,⼀模⼀样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。HTTP/2 对这⼀点做了优化,引⼊了头信息压缩机制。⼀⽅⾯,头信息使⽤ gzip 或 compress 压缩后再发送;另⼀⽅⾯,客户端和服务器同时维护⼀张头信息表,所有字段都会存⼊这个表,⽣成⼀个索引号,以后就不发送同样字段了,只发送索引号,这样就能提⾼速度了。
- 服务器推送:HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送。使⽤服务器推送提前给客户端推送必要的资源,这样就可以相对减少⼀些延迟时间。这⾥需要注意的是http2 下服务器主动推送的是静态资源,和 WebSocket 以及使⽤ SSE 等⽅式向客户端发送即时数据的推送是不同的。
队头堵塞
队头阻塞是由 HTTP 基本的“请求 - 应答”模型所导致的。HTTP 规定报⽂必须是“⼀发⼀收”,这就形成了⼀个先进先出的“串⾏”队列。队列⾥的请求是没有优先级的,只有⼊队的先后顺序,排在最前⾯的请求会被最优先处理。如果队⾸的请求因为处理的太慢耽误了时间,那么队列⾥后⾯的所有请求也不得不跟着⼀起等待,结果就是其他的请求承担了不应有的时间成本,造成了队头堵塞的现象。 HTTP/2 虽然通过多个请求复⽤⼀个 TCP 连接解决了 HTTP 的队头阻塞 ,但⼀旦发⽣丢包,就会阻塞所有 HTTP 请求——TCP 层队头阻塞。
HTTP/1.1 协议缺点
HTTP/1.1 默认使⽤了持久连接,多个请求可以复⽤同⼀个 TCP 连接,但是在同⼀个 TCP 连接⾥⾯,数据请求的通信次序是固定的。服务器只有处理完⼀个请求的响应后,才会进⾏下⼀个请求的处理,如果前⾯请求的响应特别慢的话,就会造成许多请求排队等待的情况,这种情况被称为“队头堵塞”。队头阻塞会导致持久连接在达到最⼤数量时,剩余的资源需要等待其他资源请求完成后才能发起请求。 为了避免这个问题,⼀个是减少请求数,⼀个是同时打开多个持久连接。这就是我们对⽹站优化时,使⽤雪碧图、合并脚本的原因。
HTTP/2 协议缺点
因为 HTTP/2 使⽤了多路复⽤,⼀般来说同⼀域名下只需要使⽤⼀个 TCP 连接。由于多个数据流使⽤同⼀个 TCP 连接,遵守同⼀个流量状态控制和拥塞控制。只要⼀个数据流遭遇到拥塞,剩下的数据流就没法发出去,这样就导致了后⾯的所有数据都会被阻塞。HTTP/2 出现的这个问题是由于其使⽤ TCP 协议的问题,与它本身的实现其实并没有多⼤关系。
http 3.0
- 基于 UDP 协议而非 TCP
- 实现了类似 TCP 的流量控制和可靠传输
- 集成 TLS 加密
- 实现多路复用
- 解决 TCP 队头阻塞问题
跨域 和 同源
- 跨域是浏览器的同源限制策略,当前域名的js代码试图访问其他域名下的资源会受到限制;目的是为了保护浏览器 :隔离潜在恶意文件的重要安全保护机制
- 同源:域名,协议,端口号 都要相同
- 为了解决跨域问题,可以使⽤以下⽅法之⼀:
- JSONP(JSON with Padding):这种⽅法通过在HTML⻚⾯中包含⼀个<script标签,并通过回调函数将数据返回给前端应⽤程序来实现跨域。这种⽅法通常只能⽤于GET请求。利用script标签的src属性 不受同源策略的限制
- CORS(Cross-Origin Resource Sharing):CORS是浏览器和服务器之间的⼀种协议,允许跨域资源共享。通过在服务器端添加特殊的HTTP头,可以允许浏览器在跨域情况下访问服务器资源。
服务器设置 Access-Control-Allow-Origin 等响应头,可以配置允许的请求方法、请求头、是否允许携带认证信息等
Access-Control-Allow-Origin: 允许所有域名访问
Access-Control-Allow-Methods: GET, POST, PUT 允许的 HTTP 方法
Access-Control-Allow-Headers: Content-Type, Authorization 允许的自定义头
Access-Control-Allow-Credentials: true 允许携带 Cookie
- 代理:可以在前端应⽤程序的服务器中设置代理,将前端应⽤程序的请求转发到后端API。这样,前端应⽤程序就可以通过与代理服务器的同源连接来访问后端API。
- 开发环境:webpack-dev-server、vite 等的 proxy 配置
- 生产环境:Nginx 反向代理
- Nginx:通过 Nginx 作为中间服务器,将跨域请求转发到目标服务器,隐藏真实源地址
- postMessage
- HTML5 标准中的 API
- 用于不同窗口间的跨域通信
- 可以在父子页面(iframe)或者多窗口间通信
- WebSocket
- 建立在 TCP 之上的协议
- 天然支持跨域
- 适合需要实时通信的场景
DNS查询
DNS查询是将域名转换为IP地址的过程,具体如下:
-
客户端先查本地缓存,无记录则向本地DNS服务器发送查询请求。
-
本地DNS服务器查自身缓存,若没有则根据规则转发请求,可能会经过根DNS服务器、顶级域名DNS服务器,最终找到权威DNS服务器。
-
权威DNS服务器将域名对应的IP地址返回给本地DNS服务器,本地DNS服务器缓存该记录后再返回给客户端,客户端即可用此IP地址访问目标服务器。
根域名 服务器 .
顶级域名服务器 com net cn
权威域名服务器 bilibil qq mail
本地dns- 根域名服务器 -查询 .com的顶级域名服务器地址 返回ip地址
本地dns- 顶级域名服务器查询 baidu。Com 权威域名服务器的ip地址 返回ip地址
本地dns- 权威域名服务器 查询 www.bai.com 的ip地址 返回ip地址
本地dns 保存ip地址 并返回给客户端
浏览器的缓存策略
浏览器缓存指的是浏览器将用户请求过的静态资源,存储到电脑本地磁盘中,当浏览器再次访问时,就可以直接从本地加载,不需要再去服务端请求了。
使用浏览器缓存,有以下优点:
● 减少了服务器的负担,提高了网站的性能
● 加快了客户端网页的加载速度
● 减少了多余网络数据传输
浏览器缓存的全过程
● 浏览器第一次加载资源,服务器返回 200,浏览器从服务器下载资源文件,并缓存资源文件与 response header,以供下次加载时对比使用;
● 下一次加载资源时,由于强制缓存优先级较高,先比较当前时间与上一次返回 200 时的时间差,如果没有超过 cache-control 设置的 max-age,则没有过期,并命中强缓存,直接从本地读取资源。如果浏览器不支持HTTP1.1,则使用 expires 头判断是否过期;
● 如果资源已过期,则表明强制缓存没有被命中,则开始协商缓存,向服务器发送带有 If-None-Match 和 If-Modified-Since 的请求;
● 服务器收到请求后,优先根据 Etag 的值判断被请求的文件有没有做修改,Etag 值一致则没有修改,命中协商缓存,返回 304;如果不一致则有改动,直接返回新的资源文件带上新的 Etag 值并返回 200;
● 如果服务器收到的请求没有 Etag 值,则将 If-Modified-Since 和被请求文件的最后修改时间做比对,一致则命中协商缓存,返回 304;不一致则返回新的 last-modified 和文件并返回 200
缓存字段
强缓存
通过 HTTP 响应头控制:
Cache-Control:
max-age:缓存有效时间(秒)
no-cache:需要和服务器协商验证
no-store:不使用任何缓存
private:仅浏览器可缓存
public:中间代理/CDN 等也可缓存
Expires:过期时间点(已被 Cache-Control 取代)
协商缓存
通过以下响应头实现:
Last-Modified/If-Modified-Since:基于文件修改时间
ETag/If-None-Match:基于文件内容哈希值
点击刷新按钮或者按 F5、按 Ctrl+F5 (强制刷新)、地址栏回车有什么区别?*
-
点击刷新按钮或者按 F5:浏览器直接对本地的缓存文件过期,但是会带上If-Modifed-Since,If-None-Match,这就意味着服务器会对文件检查新鲜度,返回结果可能是 304,也有可能是 200。
-
用户按 Ctrl+F5(强制刷新):浏览器不仅会对本地文件过期,而且不会带上 If-Modifed-Since,If-None-Match,相当于之前从来没有请求过,返回结果是 200。
-
地址栏回车: 浏览器发起请求,按照正常流程,本地检查是否过期,然后服务器检查新鲜度,最后返回内容
强缓存失效 强缓存和协商缓存都失效 正常流程
用户输入网址到最终渲染出来,发生了哪些事情?
0:url 检测 纠错补全,检查url的格式 1. DNS 解析出 IP 地址(dns域名解析的过程 2. 建立 TCP 连接 (三次握手 SSL握手 3. 客户端准备请求 请求头/请求体 发出 HTTP 请求 4. 服务端响应 HTTP 请求 5. 浏览器收到响应头 6. 浏览器处理响应头 cokie 设置 content-type 返回的是网页,还是图片资源,处理状态码,connection keep-alive 7. 接收响应体 9. 渲染 10. 解析 (预处理线程,css 预处理线程,对css文件进行下载和解析;资源加载:defer async) 11. 渲染主线程:浏览器解析 HTML ,生成dom树和 cssom树 ;样式计算;布局;分层;绘制;合成线程:分块;栅格化;绘制 13. Tcp关闭连接(根据 connection 是否是 keep-alive 如果是close 服务器主动关闭tcp连接)
服务器端主要工作:
URL 解析与路由匹配
- 接收请求:服务器通过网络监听指定端口,接收客户端(浏览器)发送的 HTTP 请求,其中包含了用户输入的 URL 信息。
- 解析 URL:服务器提取 URL 中的各个部分,如协议(http/https)、域名、端口、路径、查询参数等。例如,对于 URL
https://www.example.com:8080/blog/article?id=123,服务器会解析出协议为https,域名为www.example.com,端口为8080,路径为/blog/article,查询参数为id=123。 - 路由匹配:服务器根据解析出的路径信息,在路由表中查找对应的路由规则,确定应该调用哪个控制器或处理函数来处理该请求。比如,
/blog/article路径可能对应一个获取文章详情的控制器函数。
处理请求与生成响应
- 调用业务逻辑:找到匹配的路由后,服务器调用相应的业务逻辑函数或控制器方法。这可能涉及到从数据库中查询数据、调用其他服务接口、进行数据处理和计算等操作。以获取文章详情为例,服务器会根据查询参数
id从数据库中查询对应的文章数据。 - 生成响应内容:业务逻辑处理完成后,服务器将处理结果生成响应内容。通常,响应内容可以是 HTML 页面、JSON 数据、XML 数据等格式。如果是渲染页面,服务器可能会使用模板引擎,将数据填充到模板中,生成最终的 HTML 字符串。
响应返回
-
设置响应头:服务器在返回响应之前,会设置一系列的响应头信息,如
Content-Type(指定响应内容的类型,如text/html、application/json等)、Content-Length(响应内容的长度)、Cache-Control(缓存控制策略)等。这些响应头信息告诉客户端如何处理和解析响应内容。 -
发送响应:服务器将设置好响应头和响应内容后,通过网络将响应发送回客户端。客户端接收到响应后,会根据响应头和内容进行后续的处理,如渲染页面、解析 JSON 数据等。
在整个过程中,服务器端需要高效地处理并发请求,确保数据的准确性和安全性,并根据不同的请求返回合适的响应,以满足客户端的需求。
浏览器渲染页面的过程
当浏览器接收到服务器响应的资源后,首先会对资源进行解析:
- 查看响应头的信息,根据不同的指示做对应处理,比如重定向,存储cookie,解压gzip,缓存资源等等
- 查看响应头的 Content-Type的值,根据不同的资源类型采用不同的解析方式
1. 加载阶段:
加载阶段:浏览器会从上到下的加载一个HTML页面,并解析文档中的内容,如果遇到外部资源,比如css文件图片或者js文件,浏览器发起额外 的 http请求去获取他们。
当浏览器加载到js文件时,默认情况下,浏览器默认会暂停html的解析,等待js的加载和执行完成,才会处理后续的内容,除非脚本使用了defer和async异步,否则js会阻塞文档解析。
这是因为js可能会修改dom结构,浏览器需要确保解析和执行顺序一致,当html逐步解析完成,并且关键的资源(如css)已加载后,浏览器就会开始构建页面的渲染结构。
2. 构建阶段:
- 将HTML构建为DOM树
- css文件构建为CSSOM树
- 两棵树进一步合并,生成渲染树。渲染树只包含可见元素,如果一个元素的display为none被应用,就不会进入渲染树。而像是opacity:0 或者 是 visiale:hidden这类。仍然会在渲染树上,但不会被绘制。
3. 渲染阶段:
根据渲染树,浏览器会计算每个节点的布局信息,比如大小,位置等,根据计算好的信息,将页面绘制到屏幕上,将最终的网页展示给我们
4. 优化
浏览器是单线程渲染的,任务过多,过于耗时,会导致页面卡顿。
- 1、减少Dom操作。 根据批量更新机制合并dom操作,减少页面渲染消耗,避免频繁的触发重排和重绘。 常见解决方案DocumentFragment进行批量更新,减少回流和重绘。
- 2、动画优化 使用css动画替代js动画,多用transform、opacity等属性,可以在GPU上运行,提高性能。
- 3、图片视频等资源,使用懒加载技术,避免一次性加载过多内容
- 4、web worker来分担耗时任务,在独立线程里面执行js代码,以处理耗时任务。帮助开发者将耗时任务放入单独的线程,避免页面卡顿,因此不会阻塞主线程的任务。
使用 CSS 动画替代 JS 动画
并多用transform、opacity等属性可以在 GPU 上运行从而提高性能,主要原因如下:
- GPU 硬件加速:GPU 专门用于处理图形相关的任务,对于
transform(变形)和opacity(透明度)等属性的变化,浏览器可以将其识别为图形操作,并利用 GPU 的硬件加速功能来处理。GPU 能够并行处理大量的图形数据,在处理这些属性的动画时,能够快速地计算和更新图形的状态,而不需要像 CPU 那样逐个处理,从而大大提高了动画的流畅度和性能。 - 减少重排和重绘:当使用 CSS 的
transform和opacity属性来实现动画时,通常不会引起页面的重排(reflow)和重绘(repaint)。重排会重新计算元素的布局,重绘则会重新绘制元素的外观,这两个操作在性能上都比较昂贵,尤其是在频繁发生时。而transform和opacity的动画变化是在合成层(compositing layer)上进行的,只需要更新合成层的属性,不需要重新计算布局和绘制整个页面,从而减少了性能开销。 - 浏览器优化:现代浏览器对 CSS 动画进行了大量的优化。浏览器会自动将一些 CSS 动画相关的操作分配到 GPU 线程中执行,以充分利用 GPU 的性能。同时,浏览器还会对 CSS 动画进行缓存和优化,例如对动画过程中的中间状态进行缓存,避免重复计算,进一步提高了动画的性能。
- 事件处理和渲染分离:CSS 动画由浏览器的渲染引擎负责处理,与 JavaScript 的事件处理和其他脚本执行是分离的。这意味着 CSS 动画可以在不阻塞 JavaScript 线程的情况下独立运行,不会因为 JavaScript 的执行而导致动画卡顿。而 JS 动画可能会受到 JavaScript 代码执行顺序、事件处理等因素的影响,导致动画的流畅度受到影响。
XSS攻击
XSS 攻击,全称为跨站脚本攻击(Cross - Site Scripting),是一种常见的网络安全漏洞,以下是关于它的详细介绍:
定义
攻击者通过在目标网站中注入恶意脚本,使得用户在访问该网站时,浏览器会执行这些恶意脚本,从而达到窃取用户信息、破坏网站功能或进行其他恶意操作的目的。
攻击类型
- 反射型 XSS:攻击者构造一个包含恶意脚本的 URL,诱使用户点击。当用户访问该 URL 时,服务器将恶意脚本作为响应的一部分返回给浏览器,浏览器执行该脚本,从而导致攻击发生。这种攻击通常通过电子邮件、即时通讯工具等方式传播。
- 存储型 XSS:攻击者将恶意脚本存储在目标网站的数据库中,例如在评论区、留言板等地方输入恶意脚本。当其他用户访问包含该恶意脚本的页面时,浏览器会从服务器获取并执行该脚本,实现攻击。
- DOM 型 XSS:攻击者通过修改页面的 DOM 结构来注入恶意脚本。这种攻击不依赖于服务器端的响应,而是利用浏览器端的 DOM 操作漏洞,在用户浏览页面时动态地插入恶意脚本。
攻击危害
- 窃取用户信息:如用户的登录凭证、个人资料、银行卡信息等,进而导致用户的账号被盗用,财产遭受损失。
- 篡改页面内容:攻击者可以修改网页的显示内容,破坏网站的正常展示,甚至发布虚假信息,误导用户。
- 执行恶意操作:例如发起钓鱼攻击,诱导用户输入敏感信息;或者利用用户的身份在网站上进行非法操作,如发布恶意评论、删除数据等。
防范措施
通过前面介绍,看到XSS攻击的两大要素:
- 攻击者提交恶意代码
- 浏览器执行恶意代码
针对第一个要素,我们在用户输入的过程中,过滤掉用户输入的恶劣代码,然后提交给后端,但是如果攻击者绕开前端请求,直接构造请求就不能预防了
而如果在后端写入数据库前,对输入进行过滤,然后把内容给前端,但是这个内容在不同地方就会有不同显示,数据会被转码无法正常表示。
过滤并非可靠的,下面就要通过防止浏览器执行恶意代码:
在使用 .innerHTML、.outerHTML、document.write() 时要特别小心,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用 .textContent、.setAttribute() 等。
如果用 Vue/React 技术栈,并且不使用 v-html/dangerouslySetInnerHTML 功能,就在前端 render 阶段避免 innerHTML、outerHTML 的 XSS 隐患
DOM 中的内联事件监听器,如 location、onclick、onerror、onload、onmouseover 等,<a> 标签的 href 属性,JavaScript 的 eval()、setTimeout()、setInterval() 等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,请务必避免。
- 输入验证和过滤:对用户输入的内容进行严格的验证和过滤,防止恶意脚本被注入到网站中。可以使用正则表达式等方法对输入进行检查,限制输入的字符类型和长度。
- 输出编码:在将用户输入的内容输出到页面上时,对其进行编码处理,将特殊字符转换为 HTML 实体,使浏览器将其作为普通文本显示,而不是执行脚本。
- 使用安全的开发框架:许多现代的 Web 开发框架都提供了内置的安全机制,如对 XSS 攻击的防护。开发人员应选择安全可靠的框架,并遵循其安全规范进行开发。
- 设置 HTTP 头部字段:通过设置
Content - Security - Policy等 HTTP 头部字段,限制浏览器可以加载的资源来源,防止浏览器执行来自非信任源的脚本,从而降低 XSS 攻击的风险。
CSRF
CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。
利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作目的。
一个典型的CSRF攻击有着如下的流程:
- 受害者登录a.com,并保留了登录凭证(Cookie)
- 攻击者引诱受害者访问了b.com
- b.com 向 a.com 发送了一个请求:a.com/act=xx。浏览器会默认携带a.com的Cookie
- a.com接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求
- a.com以受害者的名义执行了act=xx
- 攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让a.com执行了自己定义的操作
csrf可以通过get请求,即通过访问img的页面后,浏览器自动访问目标地址,发送请求。
CSRF的特点
- 攻击一般发起在第三方网站,而不是被攻击的网站。被攻击的网站无法防止攻击发生
- 攻击利用受害者在被攻击网站的登录凭证,冒充受害者提交操作;而不是直接窃取数据
- 整个过程攻击者并不能获取到受害者的登录凭证,仅仅是“冒用”
- 跨站请求可以用各种方式:图片URL、超链接、CORS、Form提交等等。部分请求方式可以直接嵌入在第三方论坛、文章中,难以进行追踪
CSRF的预防
CSRF通常从第三方网站发起,被攻击的网站无法防止攻击发生,只能通过增强自己网站针对CSRF的防护能力来提升安全性
防止csrf常用方案如下:
-
阻止不明外域的访问
- 同源检测
- Samesite Cookie
-
提交时要求附加本域才能获取的信息
- CSRF Token
- 双重Cookie验证
这里主要讲讲token这种形式,流程如下:
- 用户打开页面的时候,服务器需要给这个用户生成一个Token
- 对于GET请求,Token将附在请求地址之后。对于 POST 请求来说,要在 form 的最后加上
<input type=”hidden” name=”csrftoken” value=”tokenvalue”/>
- 当用户从客户端得到了Token,再次提交给服务器的时候,服务器需要判断Token的有效性
CDN
CDN 即内容分发网络(Content Delivery Network)。
CDN就是根据用户位置分配最近的资源。
构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN 的关键技术主要有内容存储和分发技术
于是,用户在上网的时候不用直接访问源站,而是访问离他“最近的”一个 CDN 节点,术语叫边缘节点,其实就是缓存了源站内容的代理服务器
工作原理
在没有应用CDN时,我们使用域名访问某一个站点时的路径为
用户提交域名→浏览器对域名进行解释→
DNS解析得到目的主机的IP地址→根据IP地址访问发出请求→得到请求数据并回复
应用CDN后,DNS 返回的不再是 IP 地址,而是一个CNAME(Canonical Name ) 别名记录,指向CDN的全局负载均衡
CNAME实际上在域名解析的过程中承担了中间人(或者说代理)的角色,这是CDN实现的关键
负载均衡系统
由于没有返回IP地址,于是本地DNS会向负载均衡系统再发送请求 ,则进入到CDN的全局负载均衡系统进行智能调度:
- 看用户的 IP 地址,查表得知地理位置,找相对最近的边缘节点
- 看用户所在的运营商网络,找相同网络的边缘节点
- 检查边缘节点的负载情况,找负载较轻的节点
- 其他,比如节点的“健康状况”、服务能力、带宽、响应时间等
结合上面的因素,得到最合适的边缘节点,然后把这个节点返回给用户,用户就能够就近访问CDN的缓存代理
缓存代理
缓存系统是 CDN的另一个关键组成部分,缓存系统会有选择地缓存那些最常用的那些资源
其中有两个衡量CDN服务质量的指标:
- 命中率:用户访问的资源恰好在缓存系统里,可以直接返回给用户,命中次数与所有访问次数之比
- 回源率:缓存里没有,必须用代理的方式回源站取,回源次数与所有访问次数之比
缓存系统也可以划分出层次,分成一级缓存节点和二级缓存节点。一级缓存配置高一些,直连源站,二级缓存配置低一些,直连用户
回源的时候二级缓存只找一级缓存,一级缓存没有才回源站,可以有效地减少真正的回源
现在的商业 CDN命中率都在 90% 以上,相当于把源站的服务能力放大了 10 倍以上
- 当用户向网站发起内容请求时,首先会经过本地 DNS(域名系统)服务器解析域名。CDN 会对这个解析过程进行干预,通常返回一个指向离用户最近、负载最轻的 CDN 节点服务器的 IP 地址。
- 用户的请求被导向该 CDN 节点服务器,若该节点存有用户所需内容,就直接将内容返回给用户;若没有,节点服务器会向源服务器请求内容,获取后一方面存储在本地,一方面返回给用户。
三、总结
CDN 目的是为了改善互联网的服务质量,通俗一点说其实就是提高访问速度
CDN 构建了全国、全球级别的专网,让用户就近访问专网里的边缘节点,降低了传输延迟,实现了网站加速
通过CDN的负载均衡系统,智能调度边缘节点提供服务,相当于CDN服务的大脑,而缓存系统相当于CDN的心脏,缓存命中直接返回给用户,否则回源
优点
- 加速访问:显著减少用户与内容服务器之间的物理距离,降低网络延迟,提高内容的加载速度。以视频网站为例,用户能更快地加载视频,减少缓冲等待时间。
- 减轻服务器负载:承担了大量的内容分发任务,源服务器无需处理所有用户的请求,从而降低源服务器的压力,提高其稳定性和可靠性。
- 提高可用性和稳定性:具备多个分布广泛的节点,即使某个节点出现故障,也能通过其他节点为用户提供服务,确保服务的持续可用性。同时,还能有效抵御网络攻击,如 DDoS 攻击,保障网站的正常运行。
- 优化网络性能:对内容进行智能缓存和分发,优化网络流量,减少网络拥塞,提高整个网络的传输效率。
应用场景
- 网站加速:各类网站,尤其是内容丰富、访问量大的网站,如新闻网站、电商网站等,通过 CDN 可以快速响应用户请求,提升用户体验。、
- 压缩文件资源
标签页之间的通信
支持跨域的方式
postMessage:postMessage是专门为跨窗口通信设计的 API,它可以在不同源(跨域)的窗口之间进行安全的消息传递。你可以指定接收消息的目标窗口和消息的来源域,即使窗口的源不同,也能实现通信。在调用postMessage时,第二个参数可以指定允许接收消息的源,如果设置为*则表示允许接收来自任何源的消息。例如:
// 在发送消息的窗口
const targetWindow = window.open('https://example.com', '_blank');
targetWindow.postMessage('这是跨域消息', 'https://example.com');
// 在接收消息的窗口
window.addEventListener('message', function (event) {
if (event.origin === 'https://yourdomain.com') {
console.log('收到跨域消息:', event.data);
}
});
- WebSocket支持跨域请求。
- 原理:通过在不同标签页中建立与同一个 WebSocket 服务器的连接,通过服务器中转实现实时双向通信。标签页之间就可以借助服务器作为中介来进行消息传递。
- WebSocket 协议本身不受同源策略的限制,只要服务器配置允许,不同源(协议、域名、端口任意一项不同)的客户端都可以与服务器建立 WebSocket 连接并进行通信。。
不支持跨域的方式
-
localStorage: -
当一个标签页修改了localStorage中的数据,会触发storage事件,其他标签页可以通过监听该事件来获取数据变化。
-
localStorage遵循同源策略,即只有在同源(协议、域名和端口都相同)的页面之间才能访问和共享localStorage中的数据。不同源的页面无法直接读取或修改其他源的localStorage内容,因此不支持跨域通信。例如,在https://example1.com页面设置的localStorage数据,https://example2.com页面无法直接获取。 -
Broadcast Channel API: -
创建一个广播频道,不同标签页可以加入同一个频道,通过该频道发送和接收消息实现通信。
-
同样遵循同源策略,只有同源的浏览器窗口、标签页、iframe 等之间才能通过
Broadcast Channel API进行通信。不同源的页面无法加入同一个广播频道并接收消息,所以不支持跨域通信。例如,在https://siteA.com创建的广播频道,https://siteB.com无法与之进行通信。
WebSocket 和 HTTP 的主要区别:
连接特性
- HTTP 是短连接:每次请求都需要建立新的 TCP 连接(除非使用 keep-alive)
- WebSocket 是持久化的长连接:只需要一次握手,后续可以持续通信
通信方式
- HTTP 是单向通信:客户端请求,服务器响应
- WebSocket 是双向通信:客户端和服务器都可以主动发送数据
数据格式
- HTTP 每次请求都要带完整的 HTTP 头
- WebSocket 第一次握手完成后,后续数据传输只需要很小的头部
应用场景
-
HTTP 适合一次性的数据交互
-
WebSocket 适合实时性要求高的场景,如:
- 实时聊天
- 游戏实时数据
- 实时协作文档
性能
- WebSocket 的性能和效率通常优于 HTTP 轮询
- WebSocket 可以更好地节省服务器资源和带宽
支持性
- HTTP 被所有浏览器支持
- WebSocket 需要浏览器支持(现代浏览器普遍已支持)
Websocket
Websocket是一种协议,在服务器和客户端之间提供低延迟,全双工和长期运行的连接。解决实时通信的问题。
全双工是一种通信方式,通信的双放可以同时发送和接收数据,不需要等待对方的响应或传输完成。
传统通信:电子邮件,存在延迟,需要用户主动请求来获取更新数据。
实时通信:视频,可以实时的数据传输和交流,不需要用户主动请求或刷新去获取更新数据
WebSocket之前的解决方法:
轮询
客户端定期向服务器发送请求,询问是否有新的数据可用,服务器会检查是否有更新的数据,并将其返回给客户端。缺点会产生大量的请求和响应,造成不必要的网络开销和延迟
长轮训:
在客户端发出请求后,服务器保持连接打开,等待新数据响应后再关闭连接。
缺点:减少了无效轮训的数量,但还是需要频繁的建立和关闭连接。
webSocket应用场景:低延迟实时连接的应用
webSocket优点
webSocket优点:双向实时通信,降低延迟,可以减少请求和响应的开销,因为它的连接只需要建立一次
l 双向实时通信:允许在单个,长时间的连接上进行双向实时通信,在需要实时更新的应用中,比http更加高效。
l 降低延迟:连接一旦建立会保持开放,数据可以在双端 之间比http更低的 延迟 进行传输
l 更有效的资源利用:可以减少重复请求和响应的开销,因为它的连接只需要建立一次
Websocket 它允许服务器和客户端之间通过单个TCP连接进行双工通信并且进行实时的数据交换 。Websocket非常适合基于web的游戏,聊天应用等需要低延迟,实时连接的应用程序。*
每个语言都有对应的库,js是socket.io
建立连接过程
建立连接过程:通过HTTP发送一次常规get请求,并且在请求头中带上connection:Upgrade, Upgrade:websocket,告诉服务器要从HTTP升级成websocket,连接就建立成功,客户端和服务端可以随时进行数据交互。
工作原理
- 握手阶段:客户端向服务器发送一个 HTTP 请求,请求头中包含一些特殊的字段,如
Upgrade: websocket和Connection: Upgrade,表示客户端希望将连接升级为 WebSocket 连接。服务器收到请求后,如果支持 WebSocket 协议,会返回一个状态码为 101 的响应,表示同意升级连接。 - 连接建立:握手成功后,HTTP 连接就会被升级为 WebSocket 连接,双方可以开始进行双向通信。在这个阶段,数据以帧的形式在客户端和服务器之间传输。
- 数据传输:WebSocket 使用帧来传输数据,每个帧包含一个头部和一个数据负载。头部包含了帧的类型、长度等信息,数据负载则是实际要传输的数据。可以发送文本数据或二进制数据。
- 连接关闭:当一方想要关闭连接时,会发送一个关闭帧给对方。对方收到关闭帧后,会发送一个确认关闭帧,然后双方的连接就会正式关闭。
webSocket心跳机制:
为什么使用心跳机制:为了保持WebSoket稳定的长连接,在建立连接之后,服务端和客户端之间通过心跳包来保持连接状态,以防止连接因为长时间没有数据传输而被切断。
什么是心跳包:心跳包是一种特殊的数据包,它不包含任何实际数据,只是用来维持连接状态的。
怎么使用:通常情况下心跳包由客户端和服务端定期发送一个空的数据帧,以确保双方的链接仍然有效,避免链接因为长时间没有数据传输而被中断,如果长时间没有收到对方的心跳包就可以认为连接已经断开需要重新建立连接。
webSoket限制:
不提供加密功能,不安全;
可以用SSL协议对来webSoket进行加密,确保数据安全,
也可以在服务端限制权限设置白名单或者黑名单只允许特定地址或者域名的客户端进行链接。
浏览器的限制:不支持IE10以前的版本
保持长连接需要服务器不断的维护和处理连接状态,需要优化性能,可能会对服务器的性能造成影响。不做好优化,会消耗服务器资源