如果是你立志成为全栈工程师而不是码农,那么这个一定要懂

Web前端号

2019-05-19 18:11
关注

有了前面几篇的学历积累,我们可以挑战一下今天的BOSS,这个BOSS也是我们天天见的一个操作,就是从浏览器地址栏输入URL(域名)到页面呈现,背后发生了什么。如果正常的话,现在这个过程通常在秒秒钟就完成了,好像背后没有经历什么一样。但作为前端或者全栈工程师的你,背后的故事是必会的前端面试题和知识点,不仅有利于面试通过,对以后的web开发,web优化甚至越来越受重视的web安全都非常重要。

闲话少说,言归正传,从浏览器输入URL到页面呈现,背后涉及到的动作知识点非常多,我们本着先整体再局部的原则,先把这个过程大致分为以下几个主过程:

1 DNS寻址

我们通常在浏览器数地址栏输入的URL是域名,而不是直接输入IP地址(虽然也可以这么做 ),但之前也讲过,在茫茫的网络大海中,标识服务器的并不是人类比较容易辨识的域名,而是IP地址,所以宏观角度来说,当我们输入URL并且提交的时候,第一步就是根据域名寻找目标服务器的IP地址,这个过程就是DNS域名解析。

微观角度来看,为提高效率,DNS域名解析是有层次的,具体原则就是就近原则。

首先,本地电脑会将一些经常使用的域名与响应的IP地址建立一个映射关系,并保存在系统文件hosts里。所以正常情况下,在进行DNS解析的时候,系统会优先从hosts文件中寻找对应的IP地址,如果找到就直接使用hosts文件里面的IP地址,毕竟这是最快的。

其次,如果本地hosts文件里没有这个域名一起对应的IP地址映射,那么就求助于本地DNS服务器,大概就是系统向本地DNS服务器发送请求去查询域名对应的IP地址,本地DNS服务器响应请求,找到IP地址并将结果(IP地址)返回给浏览器。

然后,如果本地DNS服务器没有找到对应的IP地址,本地DNS服务器会层层向上一级的DNS服务器发送请求,直至DNS根服务器。如果找到的话,就会进行回传,最终把找到的IP地址返回给浏览器。

以上不管是本地hosts文件还是本地DNS或者更高一级的DNS服务器,甚至到根DNS服务器,其目的就只有一个:就是域名的解析必须要有一个结果,要么有IP地址,要么就是没有。没有的话,可能是域名错误或者该域名尚未进行解析,这个就不在讨论范围之内了。

2 建立连接

通过第一步或得域名对应的IP地址后,我们就可以在茫茫网海中找到目标服务器,但是找到之后并不是迫不及待的要找人家要东西,要东西之前先得把传输通道连起来,这个就是建立连接。这个过程就是著名的TCP三次握手。

第一次握手:主机A发送位码为syn=1,随机产生seq number=x的数据包到服务器,客户端进入SYN_SEND状态,等待服务器的确认;主机B由SYN=1知道,A要求建立联机;

第二次握手:主机B收到请求后要确认联机信息,向A发送ack number(主机A的seq+1),syn=1,ack=1,随机产生seq=y的包,此时服务器进入SYN_RECV状态;

第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack number(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功。客户端和服务器端都进入ESTABLISHED状态

这个过程有点像两个陌生人在电话两头确认电话线以及对方是否能正常听到声音,以便开始说些正式和秘密的内容:

首先电话发起者A问B:你能听到我说话吗?听到请回答。

然后B听到A的询问后,也要确认下A是否还能正常,以防有些人随便发一个请求过来就把内容发出去。然后就回复A,我能听到,你还能听到我说话吗?

A在收到B的确认以及询问后,就基本可以确认A和B之间的连接以及B是稳定可靠的,也就是双方都确认对方和线路是OK的,可以开始正式的对话内容了。但此时B还在等待A的确认回复,所以这个时候A还要再次回复B:可以听到,然后两个人开始正式交谈。

三次握手在TCP协议下完成,目的是确认身份和状态,从而建立连接。为下一步的通话做准备。

3 发送请求

建立起连接之后,双方就可以开始传输数据,进行“沟通”了。首先,在请求报文中,还必须明确请求的端口是哪个,还要确认一下端口,HTTP协议默认端口是80端口。然后浏览器向服务器发送请求,这个过程涉及到上一篇提到的四层网络模型。从应用层开始,消息以HTTP请求报文的形式,在传输层、网络层、数据链路层逐层打上头部,进行传输,在服务器端接收数据的时候,再逐层解套,最终接收到HTTP协议的请求报文。

这一块比较细,敞开来讲太多了。总之四层模型的机制保证了请求报文正确完整地发送到服务器端。

4 处理并回传

服务器端接收到请求报文,就会根据请求报文提供的要求,比如端口,参数之类的,去执行响应的操作,并将执行结果以响应报文的形式回传给浏览器。至于这个响应的操作,如果请求的是静态资源,现成的,那就直接回传,如果请求的资源需要动态生成,则web服务器就会调用不同的程序和调用数据库生成最终的HTML文件,再回传给浏览器。

5 接受并渲染

同样经过层层的增加头部和去除头部,浏览器最终得到服务器返回的HTML数据,这个时候浏览器就会加载数据,根据内容开始渲染页面,数据加载完成就会触发onload的事件。

浏览器会会根据响应的内容,来处理响应。如果响应可缓存,浏览器将把响应存入缓存。

需要注意的时候,第一次浏览器获得的是HTML文件,但是HTML文件如果继续有新资源的请求,那么就会建立新的连接,跟刚刚的过程一样。比如外部的css,js,图片等文件。

至于浏览器如何根据HTML、CSS、JS构建树,渲染页面,以及如重绘(重新绘制和部分重绘),以及这个涉及到之前讲的浏览器的工作原理,这个过程就不细讲了。

6 释放连接

之前讲过TCP连接是无状态的,也就是一次性的,不会永久保存这个状态,所以双方完成一次数据的传输之后,如果没有持续的请求,那就要释放连接。

但是连接的释放也不是说断就断,而且相比三次握手建立TCP连接,TCP连接的释放需要四次挥手。需要注意的是连接是首先要客户端浏览器发起,但要释放连接,客户端和服务器端都可以发起关闭请求。之所以要四次握手,还是要确认双方都确实完成各自的工作,防止有文件还没传完就断开的连接。

这就是浏览器输入URL到页面呈现的基本过程,虽然有些细节没有讲的很细,但基本原理基本覆盖了,如有错误,欢迎更正。

举报/反馈