从输入的URL到看到页面中间发生了什么?

500 阅读7分钟

一看这种烂掉牙的问题,小case,但是面试大佬由此延伸出来的问题已经远远超越了这个问题,不信你看

简单来说分为以下8步:

  • 1、浏览器地址输入URL并回车
  • 2、浏览器查找当前URL是否有缓存,并比较缓存是否过期
  • 3、DNS解析URL对应的IP
  • 4、根据IP建立TCP链接(三次握手)
  • 5、发送HTTP请求
  • 6、服务器处理请求,浏览器接受HTTP响应
  • 7、浏览器解析并渲染页面
  • 8、关闭TCP连接(四次挥手) 话音刚落,此时一位公司的大佬打断了我,DNS是怎么解析的,他的查询规则是什么?....怎样建立tcp连接?post和get的区别是什么?万事开头难,扛过这一波就是万物骚动的春天!,加油,奥力给。

具体解析

DNS解析其实就是个递归的过程

输入www.baidu.com 网址后,首先会在本地的域名服务器中查找,没找到会去根域名服务器查找,没有再去com的顶级域名服务器中查找,如此的类推下去,直到找到IP地址。然后会把它存在本地,共下次使用。大致的过程就是 . -> .com -> baidu.com. ->www.baidu.com. (这个点对应的就是跟域名服务器,默认情况下所有的网站最后一位都是.)

DNS缓存

我们了解了解析的具体过程,看到每一个过程都有一定的消耗和时间等待,因此衍生出了DNS缓存 DNS缓存存在着多级缓存,从离浏览器最近的距离排序的话,分为浏览器缓存,系统缓存,路由器缓存,IPS缓存,根域名服务器缓存,顶级域名服务器缓存,主域名服务器缓存。

DNS 负载均衡

我们访问同一个网站,比如baidu.com 的时候,每次响应的并非同一个服务器(IP地址不同),一般大的公司都会有多台服务器来访问支撑,假设只有一个服务器,那他的性能和存储量得要多大才能支撑大量的访问呢? DNS可以返回一个合适的机器给用户,根据每台机器的负载量,该机器距离用户地理位置等,这种过程就是负载均衡。

发起TCP连接

字段分析

  • 序号:是TCP可靠传输的关键部分,序号是该报文段发送的数据组的第一个字节的序号,在TCP传输的流中,每一个字节都有一个序号,比如一个报文段的序号是300,报文段数据共有100字节,则下一个报文的序号为400,所以序号确保了TCP传输的有序性
  • 确认号:即ACK,指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到,确认号只有当ACK标志为1时才有效,比如建立连接时,SYN的报文ACK标志为0.

TCP 三次握手

为了准确无误地将数据送到目标处,TCP协议采用了三次握手的策略。在发送数据前,通信双方必须在彼此间建立一条链接,所谓的链接就是客户端和服务端的内存中保存着双方的信息,比如ip地址,端口号等。

  1. 第一次握手: 建立连接时,客户端发送给服务端一个SYN包(Seq=x),并进入SYN_SED 状态,等待服务器的确认;(SYN:同步序列编号)

  2. 第二次握手: 服务器收到SYN包并确认客户端的SYN(ack=x+1),同时也发送一个自己的SYN(seq=y)包,即SYN+ACK包,此时服务器进入SYN_RESV状态

  3. 第三次握手: 客户端收到服务器发送的SYN+ACK包,向服务器发送确认包ACK(y+1),此包发送完毕,客户端和服务器进入(TCP链接成功)的状态,完成三次握手。

作用:确认双方的接收与发送能力是否正常。 握手的过程中传送的包不包含数据,三次握手完毕后,客户端和服务器才正式开始传送数据。

为什么需要三次,两次为啥不可以?

第一次握手:客户端发送网络包,服务端收到了,这样服务端可以确认客户端的发送能力和服务端的接受能力是正常的。

第二次握手:服务端发包,客户端收到了。这样客户端可以确认服务端的接收和发送能力都是正常的,客户端的接收和发送能力是正常的。但是此时服务器并不知道客户端的接收能力是正常的。

第三次握手:客户端发包,服务端收到了。服务端可以得出结论,客户端的接收和发送能力正常,服务器自己的接收和发送能力也正常。

三次握手的过程:

image.png

四次挥手

TCP断开链接的过程分为4步,我们称之为四次挥手

第一次挥手:Client发送一个FIN,用来关闭Client到server的数据传送,Client进入FIN_WAIT_1 状态

第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序列号为收到序列号+1(与收到的SYN相同,一个FIN占用一个序列号),server进入CLOSE_wait

第三次挥手:Server 发送一个FIN,用来关闭Server到Client间数据的传送,server进入LAST_ack状态

第四次挥手:Client收到FIN后,Client进入time_wait 状态,接着发送一个ACK给server,确认序号为收到序号+1,server进入close状态,完成四次挥手

为什么客户端最后要等待 2MSL?

保证客户端发送的最后一个ACK可以到达服务器,因为这个ACK可能丢失。对于服务器我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开的报文它还没有收到,于是服务器又回重新再发一次,而客户端可以在2MSL内收到这个重复的报文,接着给出回应报文,并且会重启2MSL计时器。

为什么建立连接是3次握手,关闭链接需要4次挥手?

建立连接时,服务器在listen状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。 而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不在发送数据了但是还能接受数据,而自己也未必将全部的数据都发送给对方了,所以对方可以立即关闭,也可以发送一些数据给对方,在发送FIN报文给对方来表示同意现在关闭链接,因此己方的FIN和ACK一般会分开发送,从而导致多了一次。

三次握手和四次挥手的本质是什么?

三次握手的本质是:确认通信双方收发数据的能力
四次挥手的目的是:关闭一个链接

发送HTTP请求

HTTP的端口为80/8080,HTTPS的端口为443 发送http请求的过程就是构建HTTP请求报文通过TCP协议中发送到服务器指定端口

常见请求方法的区别(post,get)

  1. get在浏览器会退是是无害的。而post会再次发送请求
  2. get请求会被浏览器主动cache,而post不会,除非手动设置
  3. get请求只能进行url编码,而post请求支持多种编码方式
  4. get 请求参数会完整的保留在浏览器历史记录中,而post参数不会被保留
  5. get在url中的传送的长度是有限制的,而post没有
  6. get比post更不安全,get的参数直接暴露在url中,所以不能用来传递敏感信息。
  7. get 参数通过url传递,post参数放在request body中
  8. get产生一个tcp包,post产生两个tcp数据包。(get请求,浏览器会把http header和data一并发送出去,服务器响应200,而对于post,浏览器先发送header,服务器响应100 continue,浏览器在发送data,服务器响应200ok,返回数据)