🚀 作者 :“码上有前”
🚀 文章简介 :前端高频面试题
🚀 欢迎小伙伴们 点赞👍、收藏⭐、留言💬
往期精彩内容
【前端高频面试题–HTML篇】
【前端高频面试题–CSS上篇】
【前端高频面试题–CSS下篇】
【前端高频面试题–JS上篇】
【前端高频面试题–JS下篇】
【前端高频面试题–ES6篇】
【前端高频面试题–ES7-ES11】
【前端–异步编程】
【前端高频面试题–TypeScript篇】
【前端高频面试题–git篇】
【前端高频面试题–微信小程序篇】
【前端高频面试题–Vue基础篇】
【前端高频面试题–虚拟DOM篇】
【前端高频面试题–Vue3.0篇】
【前端高频面试题–Vuex上篇】
【前端高频面试题–Vuex下篇】
【前端高频面试题–Vue生命周期篇】
【前端高频面试题–Vue组件通信篇】
【前端高频面试题–Vue路由篇】
【前端-Vue3创建一个新项目】
【前端大屏自适应缩放】
【前端Vue3 + TS项目开发一般流程】
第五章传输层
TCP
概念: TCP的全称是传输控制协议是一种面向连接、可靠、基于字节流的传输层通信协议。
特点:
- 面向连接
- 可靠
- 仅支持单播
- 面向字节流
- 拥有拥塞控制
- 提供全双工通信
- 适合大、重要的文件
- 效率低、准确率高
UDP
特点:
- 面向无连接:想发直接发,不需要进行三次握手
- 有单播、组播、广播的功能:UDP 不止支持一对一的传输方式,同样支持一对多,多对多,多对一的方式,也就是说 UDP 提供了单播,多播,广播的功能。
- 面向报文
- 不可靠性:不备份数据,无连接想发就发,当网络不好或者堵塞将会丢包或者重发数据。
- 头部开销小,传输数据报文时是很高效的
- 效率高、准确率低、即时通信
- 适合小文件、适合视频会议、电话会议
TCP粘包是怎么回事,如何处理?
默认情况下, TCP 连接会启⽤延迟传送算法 (Nagle 算法), 在数据发送之前缓存他们. 如果短时间有多个数据发送, 会缓冲到⼀起作⼀次发送 (缓冲⼤⼩⻅ socket.bufferSize ), 这样可以减少 IO 消耗提⾼性能.
如果是传输⽂件的话, 那么根本不⽤处理粘包的问题, 来⼀个包拼⼀个包就好了。但是如果是多条消息, 或者是别的⽤途的数据那么就需要处理粘包.
下面看⼀个例⼦, 连续调⽤两次 send 分别发送两段数据 data1 和 data2, 在接收端有以下⼏种常⻅的情况:
A. 先接收到 data1, 然后接收到 data2 .
B. 先接收到 data1 的部分数据, 然后接收到 data1 余下的部分以及 data2 的全部.
C. 先接收到了 data1 的全部数据和 data2 的部分数据, 然后接收到了 data2 的余下的数据.
D. ⼀次性接收到了 data1 和 data2 的全部数据.
其中的 BCD 就是我们常⻅的粘包的情况. ⽽对于处理粘包的问题, 常⻅的解决⽅案有:
- 多次发送之前间隔⼀个等待时间:只需要等上⼀段时间再进⾏下⼀次 send 就好, 适⽤于交互频率特别低的场景. 缺点也很明显, 对于⽐较频繁的场景⽽⾔传输效率实在太低,不过⼏乎不⽤做什么处理.
- 关闭 Nagle 算法:关闭 Nagle 算法, 在 Node.js 中你可以通过 socket.setNoDelay() ⽅法来关闭 Nagle 算法, 让每⼀次 send 都不缓冲直接发送。该⽅法⽐较适⽤于每次发送的数据都⽐较⼤ (但不是⽂件那么⼤), 并且频率不是特别⾼的场景。如果是每次发送的数据量⽐较⼩, 并且频率特别⾼的, 关闭 Nagle 纯属⾃废武功。另外, 该⽅法不适⽤于⽹络较差的情况, 因为 Nagle 算法是在服务端进⾏的包合并情况, 但是如果短时间内客户端的⽹络情况不好, 或者应⽤层由于某些原因不能及时将 TCP 的数据 recv, 就会造成多个包在客户端缓冲从⽽粘包的情况。 (如果是在稳定的机房内部通信那么这个概率是⽐较⼩可以选择忽略的)
- 进⾏封包/拆包: 封包/拆包是⽬前业内常⻅的解决⽅案了。即给每个数据包在发送之前, 于其前/后放⼀些有特征的数据, 然后收到数据的时 候根据特征数据分割出来各个数据包。
为什么udp不会粘包?
TCP协议是⾯向流的协议,UDP是⾯向消息的协议。UDP段都是⼀条消息,应⽤程序必须以消息为单位提取数据,不能⼀次提取任意字节的数据
UDP具有保护消息边界,在每个UDP包中就有了消息头(消息来源地址,端⼝等信息),这样对于接收端来说就容易进⾏区分处理了。传输协议把数据当作⼀条独⽴的消息在⽹上传输,接收端只能接收独⽴的消息。接收端⼀次只能接收发送端发出的⼀个数据包,如果⼀次接受数据的⼤⼩⼩于发送端⼀次发送的数据⼤⼩,就会丢失⼀部分数据,即使丢失,接受端也不会分两次去接收
第六章应用层
HTTP协议
GET和POST的区别
- 应用场景: Get获取服务器资源,而Post是更新或增添服务器资源
- 是否缓存: 浏览器一般会对Get请求缓存,而很少对Post请求缓存
- 发送的报文格式: Get的发送报文实体部分为空,Post请求的报文实体一般为发送给服务器发送的数据
- 安全性: Get请求的参数会出现在URL中,而请求的URL会保留在历史记录中,相对于Post请求来说不太安全
- 请求长度: 浏览器对用户请求的URL有长度限制,因此会对Get请求请求长度产生影响。
- 参数类型: Post的参数传递支持更多的数据模型
POST和PUT请求的区别
- 功能: Put请求修改数据内容,但是不会增添数据的种类,但是Post请求可以增添数据的种类
常见的HTTP请求头和响应头
常见的请求头:
- Accept: 浏览器能处理的内容类型
- Accept-Charset: 浏览器能够显示的字符集
- Accept-Encoding: 浏览器能够处理的压缩编码
- Accept-Language: 浏览器当前设置的语言
- Connection:浏览器与服务器之间的连接类型
- Cooike当前页面设置的任何Cooike
- Host:发出请求页面所在的域
- Referer:发出请求页面的URL
- User-Agent: 浏览器的用户代理字符串
常见的响应头
- Date: 表示消息发送的时间
- server: 服务器名称
- **Connection:**浏览器与服务之间连接的类型
- Cache-Control: 控制HTTP缓存
- content-type: 表示后面的文档属于什么MIME类型
常见的Content-type属性值:
- application/x-www-form-urlencoded:浏览器的原生表单from
- multipart/form-data:常见的post提交,表单上传时使用
- application/json:Json字符串
- text/xml:提交XML格式的数据
HTTP状态码304是多好还是少好
常见的HTTP请求方法
- **GET:**提交
- **POST:**更新或新增服务器资源
- PUT: 上传数据,修改数据
- **DELETE:**删除
- OPTIONS: 询问支持的请求方法,用来跨域请求
- HEAD: 获取报文首部,与GET相比不返回报文主体
OPTIONS请求方法及场景
通过这个方法,客户端可以在采取具体资源请求之前,决定对该资源采取何种必要措施,或者了解服务器的性能。该请求方法的响应不能缓存。
主要用途:
- 获取服务器支持的所有HTTP请求方法
- 用来检查访问权限,在进行跨域CORS共享时,对于复杂请求,使用OPTIONS来进行嗅探请求,以判断是否父指定资源的访问权限
HTTP1.0 和HTTP1.1的区别
- 连接方面: http1.0 默认使用非持久连接,而 http1.1 默认使用持久连接。http1.1 通过使用持久连接来使多个 http 请求复用同一个 TCP 连接
- 资源请求方面: http1.1 则在请求头引入了 range 头域,它允许只请求资源的某个部分,即返回码是 206(Partial Content),而不像在 http1.0 中将整个对象全部送过来
- 缓存方面: http1.0 中主要使用 header 里的 If-Modified-Since、Expires 来做为缓存判断的标准,http1.1 则引入了更多的缓存控制策略,例如 Etag、If-Unmodified-Since、If-Match、If-None-Match 等更多可供选择的缓存头来控制缓存策略。
- 新增host字段: 用来指定服务器的域名。
HTTP1.1 和HTTP2.0的区别
- 二进制协议: HTTP/2 是一个二进制协议。
- 多路复用: HTTP/2 实现了多路复用,HTTP/2 仍然复用 TCP 连接,但是在一个连接里,客户端和服务器都可以同时发送多个请求或回应,而且不用按照顺序发送,这样就避免了"队头堵塞"的问题。
- 数据流: HTTP/2 使用了数据流的概念,因为 HTTP/2 的数据包是不按顺序发送的,同一个连接里面连续的数据包,可能属于不同的请求。
- 头信息压缩: HTTP/2 实现了头信息压缩, HTTP 1.1 协议不带状态,每次请求都必须附上所有信息。
- 服务器推送: HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送。
HTTP 和HTTPS的区别
- HTTPS协议需要CA协议,费用更高;而HTTP不需要
- HTTPS具有安全性的SSL加密传输协议,而HTTP协议则是超文本传输协议,传输的是明文
- 使用不同的连接方式和端口。HTTPS协议端口是443,而HTTP协议端口是80
- HTTPS协议机油SSL和HTTP协议构建的可进行加密传输,身份验证的网络协议,比HTTP更安全。而HTTP西医连接简单是无状态的。
当浏览器中输入网址并安歇回车之后发生过程
- 解析URL:首先判断是否惨仔非法字符与不符合URL的字符,其次判断URL中的协议或者主机名是否合法,然后开始协解析URL
- 缓存判断:浏览器判断请求是否存在缓存,如果存在并且还没有失效,那么直接使用,否则向服务器发送请求
- DNS解析:使用DNS协议,将域名解析为IP地址。首先判断该域名的IP地址本地是否存在缓存,如果没有则使用迭代或者递归的方法找到域名服务区并解析该域名为IP地址,最后将IP地址返回给请求的用户。
- 获取MAC地址:当浏览器获取到IP地址后,数据传输还需要知道目的主机MAC地址,因为应用层下发数据给传输层,TCP协议会指定断后号和目的端口号,然后下发给网络层。网络层会将本机地址作为源地址获取的IP地址作为目的地址。到数据链路层,数据的发生需要加入双方的MAC地址,本机的MAC地址作为源地址,目的MAC地址需要分情况处理。通过将IP地址与本机的子网掩码相与,可以判断是否与请求主机在同一子网里,在同一子网,则使用APR协议获取目的主机的MAC地址,如果不在同一网段,那么请求转发给网关,此时还是通过APR协议来获取网关的MAC地址,此时目的主机MAC地址即为网关的地址。
- TCP三次握手:首先客户端向服务器发送一个 SYN 连接请求报文段和一个随机序号,服务端接收到请求后向服务器端发送一个 SYN ACK报文段,确认连接请求,并且也向客户端发送一个随机序号。客户端接收服务器的确认应答后,进入连接建立的状态,同时向服务器也发送一个ACK 确认报文段,服务器端接收到确认后,也进入连接建立状态,此时双方的连接就建立起来了。
- HTTPS握手 :如果使用的是 HTTPS 协议,在通信前还存在 TLS 的一个四次握手的过程。
- 返回数据:当页面请求发送到服务器端后,服务器端会返回一个 html 文件作为响应,浏览器接收到响应后,开始对 html 文件进行解析,开始页面的渲染过程。
- 页面渲染 :浏览器首先会根据 html 文件构建 DOM 树,根据解析到的 css 文件构建 CSSOM 树,如果遇到 script 标签,则判端是否含有 defer 或者 async 属性,要不然 script 的加载和执行会造成页面的渲染的阻塞。当 DOM 树和 CSSOM 树建立好后,根据它们来构建渲染树。渲染树构建好后,会根据渲染树来进行布局。布局完成后,最后使用浏览器的 UI 接口对页面进行绘制。这个时候整个页面就显示出来了。
- TCP四次挥手 :最后一步是 TCP 断开连接的四次挥手过程。若客户端认为数据发送完成,则它需要向服务端发送连接释放请求。服务端收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入 CLOSE_WAIT 状态,此时表明客户端到服务端的连接已经释放,不再接收客户端发的数据了。但是因为 TCP 连接是双向的,所以服务端仍旧可以发送数据给客户端。
对Keep-alive的理解
HTTP1.0 中默认是在每次请求/应答,客户端和服务器都要新建一个连接,完成之后立即断开连接,这就是短连接。
当使用Keep-Alive模式时,Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接,这就是长连接。其使用方法如下:
HTTP1.0版本是默认没有Keep-alive的(也就是默认会发送keep-alive),所以要想连接得到保持,必须手动配置发送Connection: keep-alive字段。若想断开keep-alive连接,需发送Connection:close字段;
HTTP1.1规定了默认保持长连接,数据传输完成了保持TCP连接不断开,等待在同域名下继续用这个通道传输数据。如果需要关闭,需要客户端发送Connection:close首部字段。
Keep-Alive的建立过程:
-
客户端向服务器在发送请求报文同时在首部添加发送Connection字段
-
服务器收到请求并处理 Connection字段
-
服务器回送Connection:Keep-Alive字段给客户端
-
客户端接收到Connection字段
-
Keep-Alive连接建立成功
服务端自动断开过程(也就是没有keep-alive): -
客户端向服务器只是发送内容报文(不包含Connection字段)
-
服务器收到请求并处理
-
服务器返回客户端请求的资源并关闭连接
-
客户端接收资源,发现没有Connection字段,断开连接
客户端请求断开连接过程: -
客户端向服务器发送Connection:close字段
-
服务器收到请求并处理connection字段
-
服务器回送响应资源并断开连接
-
客户端接收资源并断开连接
开启Keep-Alive的优点:
- 较少的CPU和内存的使⽤(由于同时打开的连接的减少了);
- 允许请求和应答的HTTP管线化;
- 降低拥塞控制 (TCP连接减少了);
- 减少了后续请求的延迟(⽆需再进⾏握⼿);
- 报告错误⽆需关闭TCP连;
开启Keep-Alive的缺点: - 长时间的Tcp连接容易导致系统资源无效占用,浪费系统资源。
页面多张图片,HTTP怎么加载表现?
- 在HTTP 1下,浏览器对一个域名下最大TCP连接数为6,所以会请求多次。可以用多域名部署解决。这样可以提高同时请求的数目,加快页面图片的获取速度。
- 在HTTP 2下,可以一瞬间加载出来很多资源,因为,HTTP2支持多路复用,可以在一个TCP连接中发送多个HTTP请求。
HTTP请求报文是怎么样的?
请求报文分四部分:请求行,请求头,空行,请求体
HTTP响应报文是怎么样的?
请求报文有4部分组成:响应行,响应头,空行,响应体
HTTP协议的优缺点
HTTP是超文本传输协议,定义了客户端和服务器之间交换报文的格式与方式,默认端口80,使用TCP作为传输层协议吗,保证了数据传输的可靠性。
优点:
- 支持C/S模式
- 简单快速
- 无连接,无状态
缺点: - 无状态
- 明文传输
- 不安全
HTTP3.0
HTTP/3基于UDP协议实现了类似于TCP的多路复用数据流、传输可靠性等功能,这套功能被称为QUIC协议。
URL有哪些组成部分
以:www.baidu.com
- 协议部分: 协议部分分为http: 表示网页使用的是HTTP协议。在Internet中可以使用多种协议,如HTTP,FTP等
- 域名部分:
- 端口部分: 跟在域名后面的是端口,使用“:”分开,如果省略也表示采用默认端口
- 虚拟目录部分: 从域名后面的第一个“/”开始到最后一个“/”为止,是虚拟目录部分,不是一个URL的必须部分
- 文件名部分: 从域名最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”则是从域名最后的一个“/”开始对“#”为止。如果“?”和“#”都没有则从最后一个“/”开始到结束都是文件名部分。不是URL必须文本
- 锚部分: 从“#”开始到最后都是锚部分。不是URL必须的部分
- 参数部分: 从“?”开始到“#”为止之间的部分为参数部分,通常是以键值的方式组成,多个参数用“&”连接,不是URL必须部分。
与缓存有关的HTTP请求头有哪些?
强缓存: Expires、Cache-Control
协商缓存: Etag、 If-None-Match 、Last-Modified、If-Modified-Since
HTTPS
超文本传输安全协议(Hypertext Transfer Protocol Secure,简称:HTTPS)是一种通过计算机网络进行安全通信的传输协议。HTTPS经由HTTP进行通信,利用SSL/TLS来加密数据包。HTTPS的主要目的是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。
HTTP协议采用明文传输信息,存在信息窃听、信息篡改和信息劫持的风险,而协议TLS/SSL具有身份验证、信息加密和完整性校验的功能,可以避免此类问题发生。安全层的主要职责就是对发起的HTTP请求的数据进行加密操作 和 对接收到的HTTP的内容进行解密操作。
HTTP状态码
状态码类别:
类别 | 原因 | 描述 |
---|---|---|
1xx | Information(信息类状态码) | 接受的请求正在处理 |
2xx | Success(成功状态码) | 请求正常处理 |
3xx | Redirection(重定向状态) | 需要进行附加操作以 完成请求 |
4xx | Client Error(客户端错误) | 服务器无法处理请求 |
5xx | Serve Error(服务器错误) | 服务器处理请求出错 |
2XX(Success 成功状态码)
- 200 OK : 客户端发出的请求被服务器正常处理
- **204 No Content:**表示客户端发出的请求已经被服务器正常处理,但是没有返回的内容。
- **206 Partial Content :**该状态码表示客户端进行了范围请求,而服务器端执行了这部分的 GET 请求。响应报文中包含由 Content-Range 指定范围的实体内容
3XX (Redirection 重定向状态码)
浏览器需要执行某些特殊的处理以正确处理请求。
- 301 Moved Permanently: 永久重定向,请求的资源已经被分配了新的 URI,以后应使用资源指定的 URI,搜索引擎在抓取新内容的同时也将旧的网址替换为重定向之后的网址。使用场景:当我们想换个域名,旧的域名不再使用时,用户访问旧的域名用301重定向到新域名。301还可以用来告诉浏览器我们我们的目标是哪个域名
- 302 Found: 临时重定向,和301功能类似,只不过使用302的URL资源是动态的,以后还可能临时重定向其他URL。使用场景:可进行登录之后自动重定向进入活动界面。未登录的用户访问用户中心自动重定向到登录界面。访问页面404重定向到首页。
- 303 See Other:
- 304 Not Modified: 浏览器缓存相关
- **307 Temporary Redirect:**临时重定向 ,与302有着相同的含义,但是307会遵守浏览器标准,不会将浏览器Location中的POST变成GET
4XX(Client Error 客户端错误状态码)
- **400 Bad Request:**表示报文中存在语法错误,需要修改报文语法请求的内容再发生请求,浏览器对其处理会像200 OK一样
- **401 Unauthorized: ** 发送的请求需要有通过 HTTP 认证(BASIC 认证、DIGEST 认证)的认证信息。当浏览器初次接收到 401 响应,会弹出认证用的对话窗口。会出现401的情况:
- **403 Forbidden:**请求资源的访问被服务器拒绝了,服务器端没有必要给出详细理由,但是可以在响应报文实体的主体中进行说明。进入该状态后,不能再继续进行验证。该访问是永久禁止的,并且与应用逻辑密切相关。具体的还可分403.1执行访问被禁止,403.2读访问被禁止等20种情况。
- 404 Not Found: 表示服务器上无法找到请求的资源,除此之外,也可以在服务器端拒绝请求且不想说明理由时使用。
- **405 Method Not Allowed:**表示客户端请求的方法虽然能被服务器识别,但是服务器禁止使用该方法。GET 和 HEAD 方法,服务器应该总是允许客户端进行访问。客户端可以通过 OPTIONS 方法(预检)来查看服务器允许的访问方法。
5XX(Server Error 服务器错误状态码)
5XX 的响应结果表明服务器本身发生错误.
- **500 Internal Server Error:**表明服务器端在执行请求时发生了错误。也有可能是 Web 应用存在的 bug 或某些临时的故障。
- **502 Bad Gateway:**表明扮演网关或代理角色的服务器,从上游服务器中接收到的响应是无效的。
- **503 Service Unavailable:**该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。
- **504 Gateway Timeout:**表示网关或者代理的服务器无法在规定的时间内获得想要的响应。
DNS协议
概念:DNS 是域名系统 (Domain Name System) 的缩写,提供的是一种主机名到 IP 地址的转换服务。
作用: 将域名解析为IP地址
网络模型
在这里插入图片描述
- 应用层:是为计算机用户提供应用和各种网络服务。我们常见应用层的网络服务协议有:HTTP,HTTPS,FTP,POP3、SMTP等。
- 表示层 :提供各种用于应用层数据的编码、转换、压缩、加解密等功能
- 会话层 :负责建立、管理和终止表示层实体之间的通信会话。该层的通信由不同设备中的应用程序之间的服务请求和响应组成,会话管理。
- 传输层 :建立了主机端到端的链接,传输层的作用是为上层协议提供端到端的可靠、透明的数据传输服务,包括处理差错控制和流量控制等问题并规定数据包的传输方式。
- 网络层 :通过IP寻址来建立两个节点之间的连接,为源端的运输层送来的分组,路由选择和交换节点,正确无误地按照地址传送给目的端的运输层。IP协议是Internet的基础,网络层规定数据包的传输路线。
- 数据链路层:将比特组合成字节,再将字节组合成帧,使用链路层地址 (MAC地址)来介质访问,并进行差错检测。网络层与数据链路层相比,我们或许可以这样理解,网络层是规划了数据包的传输路线,而数据链路层就是传输路线。不过,在数据链路层上还增加了差错控制的功能。
- 物理层:规定了电平、速度和电缆针脚等物理设备的电气性质。
模型各层设备:
WebSocket
WebSocket的理解
为HTML5提供重要的一种浏览器和服务器进行全双工通讯的网络技术,属于应用层协议。它属于TCP传输协议,并复用HTTP的握手通道。。浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
WebSocket 的出现就解决了半双工通信的弊端。它最大的特点是:服务器可以向客户端主动推动消息,客户端也可以主动向服务器推送消息。
WebSocket原理
WebSocket特点
- 支持全双工,实时性强
- 可以发送文本,也可以发送二进制数据
- 建立在TCP协议之上,服务端更容易实现
- 数据比较轻量,性能开销小,通信高效
- 没有同源限制,客户端可以与任意服务器通信
- 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL
- 与HTTP兼容性很好,默认端口也是80和443
WebSocket的使用
WebSocket是HTML5提供的一种浏览器与服务器进行全双工通讯的网络技术,属于应用层协议。它基于TCP传输协议,并复用HTTP的握手通道。浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接, 并进行双向数据传输。
WebSocket 的出现就解决了半双工通信的弊端。
最大的特点:服务器可以向客户端主动推动消息,客户端也可以主动向服务器推送消息。
WebSocket原理:客户端向 WebSocket 服务器通知(notify)一个带有所有接收者ID(recipients IDs)的事件(event),服务器接收后立即通知所有活跃的(active)客户端,只有ID在接收者ID序列中的客户端才会处理这个事件。
WebSocket 特点的如下:
- 支持双向通信,实时性更强
- 可以发送文本,也可以发送二进制数据‘’
- 建立在TCP协议之上,服务端的实现比较容易
- 数据格式比较轻量,性能开销小,通信高效
- 没有同源限制,客户端可以与任意服务器通信
- 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL
- 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用
- HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
Websocket的使用方法:
在客户端中:
// 在index.html中直接写WebSocket,设置服务端的端口号为 9999
let ws = new WebSocket('ws://localhost:9999');
// 在客户端与服务端建立连接后触发
ws.onopen = function() {
console.log("Connection open.");
ws.send('hello');
};
// 在服务端给客户端发来消息的时候触发
ws.onmessage = function(res) {
console.log(res); // 打印的是MessageEvent对象
console.log(res.data); // 打印的是收到的消息
};
// 在客户端与服务端建立关闭后触发
ws.onclose = function(evt) {
console.log("Connection closed.");
};
即时通讯的实现:短轮询、长轮询、SSE 和 WebSocket 间的区别?
短轮询和长轮询的目的都是用于实现客户端和服务器端的一个即时通讯。
短轮询的基本思路: 浏览器每隔一段时间向浏览器发送 http 请求,服务器端在收到请求后,不论是否有数据更新,都直接进行响应。这种方式实现的即时通信,本质上还是浏览器发送请求,服务器接受请求的一个过程,通过让客户端不断的进行请求,使得客户端能够模拟实时地收到服务器端的数据的变化。这种方式的优点是比较简单,易于理解。缺点是这种方式由于需要不断的建立 http 连接,严重浪费了服务器端和客户端的资源。当用户增加时,服务器端的压力就会变大,这是很不合理的。
长轮询的基本思路: 首先由客户端向服务器发起请求,当服务器收到客户端发来的请求后,服务器端不会直接进行响应,而是先将这个请求挂起,然后判断服务器端数据是否有更新。如果有更新,则进行响应,如果一直没有数据,则到达一定的时间限制才返回。客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。长轮询和短轮询比起来,它的优点是明显减少了很多不必要的 http 请求次数,相比之下节约了资源。长轮询的缺点在于,连接挂起也会导致资源的浪费。
SSE 的基本思想: 服务器使用流信息向服务器推送信息。严格地说,http 协议无法做到服务器主动推送信息。但是,有一种变通方法,就是服务器向客户端声明,接下来要发送的是流信息。也就是说,发送的不是一次性的数据包,而是一个数据流,会连续不断地发送过来。这时,客户端不会关闭连接,会一直等着服务器发过来的新的数据流,视频播放就是这样的例子。SSE 就是利用这种机制,使用流信息向浏览器推送信息。它基于 http 协议,目前除了 IE/Edge,其他浏览器都支持。它相对于前面两种方式来说,不需要建立过多的 http 请求,相比之下节约了资源。
WebSocket 是 HTML5 定义的一个新协议,与传统的 http 协议不同,该协议允许由服务器主动的向客户端推送信息。使用 WebSocket 协议的缺点是在服务器端的配置比较复杂。WebSocket 是一个全双工的协议,也就是通信双方是平等的,可以相互发送消息,而 SSE 的方式是单向通信的,只能由服务器端向客户端推送信息,如果客户端需要发送信息就是属于下一个 http 请求了。
上面的四个通信协议,前三个都是基于HTTP协议的。
对于这四种即使通信协议,从性能的角度来看:
WebSocket > 长连接(SEE) > 长轮询 > 短轮询
但是,我们如果考虑浏览器的兼容性问题,顺序就恰恰相反了:
短轮询 > 长轮询 > 长连接(SEE) > WebSocket
所以,还是要根据具体的使用场景来判断使用哪种方式。