前端需要了解的网络通信及浏览器知识

本文经过借鉴书籍资料、他人博客总结出的知识点

从输入 URL 到页面加载完成,发生了什么?

首先需要找到这个url域名的服务器IP,为了寻找这个IP,浏览器首先会寻找缓存,查看缓存中是否有记录,缓存的查找记录为:浏览器缓存—>系统缓存—>路由器缓存;
缓存中没有则查找系统的hosts文件中是否有记录,
如果没有则查询DNS(域名解析系统)服务器,将 URL 解析为对应的 IP 地址,然后与这个 IP 地址确定的那台服务器建立起 TCP 网络连接(三次握手),
浏览器根据这个IP以及相应的端口号,构造一个http请求,这个请求报文会包括这次请求的信息,主要是请求方法请求说明请求附带的数据,并将这个http请求封装在一个tcp包中,这个tcp包会依次经过传输层网络层数据链路层物理层到达服务器,服务器解析这个请求来作出响应,返回相应的html给浏览器,因为html是一个树形结构,浏览器根据这个html来构建DOM树,在dom树的构建过程中如果遇到JS脚本和外部JS连接,则会停止构建DOM树来执行和下载相应的代码,这会造成阻塞,这就是为什么推荐JS代码应该放在html代码的后面,之后根据外部样式,内部样式,内联样式构建一个CSS对象模型树CSSOM树,构建完成后和DOM树合并为渲染树,这里主要做的是排除非视觉节点,比如script,meta标签和排除display为none的节点,之后进行布局,布局主要是确定各个元素的位置和尺寸,之后是渲染页面,因为html文件中会含有图片,视频,音频等资源,在解析DOM的过程中,遇到这些都会进行并行下载,浏览器对每个域的并行下载数量有一定的限制,一般是4-6个。
当然在这些所有的请求中我们还需要关注的就是缓存,缓存一般通过Cache-Control、Last-Modify、Expires等首部字段控制。 (Cache-Control和Expires的区别在于Cache-Control使用相对时间,Expires使用的是基于服务器端的绝对时间,因为存在时差问题,一般采用Cache-Control)在请求这些有设置了缓存的数据时,会先查看是否过期,如果没有过期则直接使用本地缓存,过期则请求并在服务器校验文件是否修改,如果上一次响应设置了ETag值会在这次请求的时候作为If-None-Match的值交给服务器校验,如果一致,继续校验 Last-Modified,没有设置ETag则直接验证Last-Modified,再决定是否返回304
渲染完毕,页面便呈现给了用户
最后,断开连接(TCP四次挥手)
在这里插入图片描述
将这个过程切分为如下的过程片段:

  1. DNS 解析
  2. TCP 连接
  3. HTTP 请求抛出
  4. 服务端处理请求,HTTP 响应返回
  5. 浏览器拿到响应数据,解析响应内容,把解析的结果渲染展示给用户
  6. 断开TCP连接

TCP3次握手和4次挥手

TCP的3次握手

过程

C-S:发送SYN=1,seq=x C端关闭━主动打开,S端关闭━被动打开
S-C: 发送ACK=1,SYN=1,ack=x+1,seq=y S端处于监听状态,C端处于同步已发送状态
C-S: 发送ACK=1,ack=y+1,seq=x+1 C端建立连接,S端建立连接

tcp3次握手
TCP的标志位

  • SYN(synchronous):建立联机

  • ACK(acknowledgement):确认

  • PSH(push):传送

  • FIN(finish):结束

  • RST(reset):重置

  • UGR(urgent):紧急
    在这里插入图片描述
    几个概念

  • seq:序号,占4个字节,范围[0,4284967296],由于TCP是面向字节流的,在一个1个TCP连接中传送字节流中国的每一个字节都按照顺序编号,此外序号是循环使用的

  • ACK: 仅当ACK=1时确认字段才有效,当ACK=0时确认字段无效,并且TCP规定,在连接建立后所有的传送报文段都必须要把ACK置为1

  • SYN:同步序列号,用来发起一个连接。当SYN=1而ACK=0时表明这是一个请求报文段;若对方同意连接,则响应报文中SYN=1,ACK=1

  • FIN :用来释放一个连接,当FIN=1表示此报文段的发送方已经发送完毕。并要求释放链接

为什么需要三次握手,两次不行吗?

弄清这个问题,我们需要先弄明白三次握手的目的是什么,能不能只用两次握手来达到同样的目的。

  • 第一次握手:客户端发送网络包,服务端收到了。 这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
  • 第二次握手:服务端发包,客户端收到了。
    这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
  • 第三次握手:客户端发包,服务端收到了。 这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。

因此,需要三次握手才能确认双方的接收与发送能力是否正常。

TCP的4次挥手

过程

C-S:FIN=1,seq=x C建立连接状态━终止等待1,S端建立连接到━关闭等待
S-C:ACK=1,ack=x+1,seq=v S关闭等待持续,C终止等待1━终止等待2
S-C:ACK=1,FIN=1,seq=y,ack=x+1 C端终止等待━时间等待,S最后确认
C-S:ACK=1,ack=y+1,seq=x+1 C端时间等待持续一会后关闭,S端关闭
在这里插入图片描述

  1. 客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入FIN_WAIT_1 状态。
  2. 服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSED_WAIT 状态。
  3. 客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。
  4. 等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。
  5. 客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态。
  6. 服务器收到了 ACK 应答报文后,就进入了 CLOSE 状态,至此服务端已经完成连接的关闭。
  7. 客户端在经过 2MSL 一段时间后,自动进入 CLOSE 状态,至此客户端也完成连接的关闭。
为什么挥手需要4次?

再来回顾下四次挥手双方发 FIN 包的过程,就能理解为什么需要四次了。

  • 关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。
  • 服务器收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送FIN报文给客户端来表示同意现在关闭连接。

从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK 和 FIN 一般都会分开发送,从而比三次握手导致多了一次。

为什么 TIME_WAIT 等待的时间是 2MSL

MSL 是 Maximum Segment Lifetime,报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为TCP 报文基于是 IP 协议的,而 IP 头中有一个 TTL 字段,是 IP 数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减 1,当此值为 0 则数据报将被丢弃,同时发送 ICMP 报文通知源主机。

MSL 与 TTL 的区别:MSL 的单位是时间,而 TTL 是经过路由跳数。所以 MSL 应该要大于等于 TTL 消耗为 0 的时间,以确保报文已被自然消亡。

TIME_WAIT 等待 2 倍的 MSL,比较合理的解释是:网络中可能存在来自发送方的数据包,当这些发送方的数据包被接收方处理后又会向对方发送响应,所以一来一回需要等待 2 倍的时间。

比如,如果被动关闭方没有收到断开连接的最后的 ACK 报文,就会触发超时重发 Fin 报文,另一方接收到 FIN 后,会重发 ACK 给被动关闭方, 一来一去正好 2 个 MSL。

2MSL 的时间是从客户端接收到 FIN 后发送 ACK 开始计时的。如果在 TIME-WAIT 时间内,因为客户端的 ACK 没有传输到服务端,客户端又接收到了服务端重发的 FIN 报文,那么 2MSL 时间将重新计时。

在 Linux 系统里 2MSL 默认是 60 秒,那么一个 MSL 也就是 30 秒。Linux 系统停留在 TIME_WAIT 的时间为固定的 60 秒。

其定义在 Linux 内核代码里的名称为 TCP_TIMEWAIT_LEN:

#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT 
                                    state, about 60 seconds  */

如果要修改 TIME_WAIT 的时间长度,只能修改 Linux 内核代码里 TCP_TIMEWAIT_LEN 的值,并重新编译 Linux 内核。

为什么需要 TIME_WAIT 状态?

主动发起关闭连接的一方,才会有 TIME-WAIT 状态。

需要 TIME-WAIT 状态,主要是两个原因:

  • 防止具有相同「四元组」的「旧」数据包被收到;
  • 保证「被动关闭连接」的一方能被正确的关闭,即保证最后的 ACK 能让被动关闭方接收,从而帮助其正常关闭;

更多内容 https://juejin.cn/post/6844903958624878606 https://blog.csdn.net/fangmeng1997/article/details/104023499

http和https;http0.9、http1.0、http1.1、http2.0

GETPOST的区别

GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同

  • 首先最直观的是语义上的区别。

  • 从缓存的角度:GET 请求会被浏览器主动缓存下来,留下历史记录,而 POST 默认不会。

  • 从参数的角度:GET把参数包含在URL中,POST通过request body传递参数,所以POSTGET安全;GET请求在URL中传送的参数是有长度限制的,而POST没有;

  • 对参数的数据类型:GET只接受ASCII字符,而POST没有限制;

  • 从编码的角度:GET请求只能进行url编码,只能接收 ASCII 字符。而POST支持多种编码方式;

  • 从幂等性的角度:GET是幂等的,而POST不是。(幂等表示执行相同的操作,结果也是相同的)

  • GET在浏览器回退时是无害的,而POST会再次提交请求;

  • GET产生的URL地址可以被Bookmark,而POST不可以;

  • GET请求会被浏览器主动cache,而POST不会,除非手动设置;

  • TCP的角度:GET产生一个TCP数据包;POST产生两个TCP数据包。

对于GET方式的请求,浏览器会把http headerdata一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

  1. GET与POST都有自己的语义,不能随便混用。
  2. 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
  3. 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

TCP和UDP的区别

WebSocket的实现和应用

Websocket原理

几个很实用的BOM属性对象方法

Cookie、sessionStorage、localStorage的区别

具有代表性的 HTTP 状态码

100 继续
200 成功
204 请求成功,但没有资源返回
206 对资源一部分进行请求
301 永久性重定向
302 暂时性重定向
303 暂时性重定向,且需要用GET方法
304 资源找到但不符合请求条件
307 暂时性重定向,且不会自动将POST改为GET
400 请求报文中出现语法错误
401 请求需要通过http认证
403 服务器拒绝访问该资源
404 未找到该资源
500 服务器执行请求时发生错误
503 服务器处于超负载或停机维护
504 服务器超时

web worker

iframe是什么?有什么缺点?

标签是一个内联框架,即用来在当前 HTML 页面中嵌入另一个文档的,且所有主流浏览器都支持iframe标签。

基本语法:

标签常用属性介绍:

height可以设置框架显示的高度

width可以设置框架显示的宽度

name可以定义框架的名称

frameborder用来定义是否需要显示边框,取值为1表示需要边框

scrolling用来设置框架是否需要滚动条,取值可以是yes,no,auto

src用于设置框架的地址,可以使页面地址,也可以是图片地址

align用于设置元素对齐方式,取值可以是left,right,top,middle,bottom

以上属性可以根据需要进行设置。

优点:
iframe能够原封不动的把嵌入的网页展现出来。
如果有多个网页引用iframe,那么你只需要修改iframe的内容,就可以实现调用的每一个页面内容的更改,方便快捷。
网页如果为了统一风格,头部和版本都是一样的,就可以写成一个页面,用iframe来嵌套,可以增加代码的可重用。
如果遇到加载缓慢的第三方内容如图标和广告,这些问题可以由iframe来解决。

缺点:
iframe会阻塞主页面的onload事件;
iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。,会产生很多页面,不容易管理。
iframe框架结构有时会让人感到迷惑,如果框架个数多的话,可能会出现上下、左右滚动条,会分散访问者的注意力,用户体验度差。
代码复杂,无法被一些搜索引擎索引到,这一点很关键,现在的搜索引擎爬虫还不能很好的处理iframe中的内容,所以使用iframe会不利于搜索引擎优化(SEO)。
很多的移动设备无法完全显示框架,设备兼容性差。
iframe框架页面会增加服务器的http请求,对于大型网站是不可取的。

现在基本上都是用Ajax来代替iframe,所以iframe已经渐渐的退出了前端开发。
如果需要使用iframe,最好是通过javascript动态给iframe添加src属性值,这样可以绕开以上一些问题。

DOCTYPE的作用

RESTful

用 URL 定位资源,用 HTTP 动词(GET,POST,DELETE,PUT)描述操作。

click在ios上有300ms延迟,原因及如何解决?

浏览器缓存机制(强缓存和协商缓存)

强缓存和协商缓存

10种跨域解决方案

9种跨域解决方案

常见的Web前端攻击总结

线程与进程的区别

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值