我愿称之为绝杀面试题,计算机网络方面的知识甚至浏览器的渲染机制,同时考察知识面的广度和深度,面试官问这一个题就足以探清你这方面知识的掌握情况。另一方面了解这其中的细节,对于前端优化来说也至关重要,本文也只能尽自己所了解到的进行总结。
从输入url到加载完页面主要发生了以下过程(不考虑CDN和资源的强缓存):
一、DNS解析
二、建立TCP连接
三、客户端发送HTTP请求
四、服务端返回资源
五、浏览器渲染页面
六、断开TCP连接
一、DNS解析
什么是DNS?
DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。
DNS解析的详细过程:
1、解析域名时,浏览器会首先会依次查看自己的DNS缓存、操作系统中的DNS缓存、本地硬盘的 hosts 文件、路由器缓存,看看其中有没有缓存和这个域名对应的ip地址,如果有的话就直接使用 。
2、如果在上面的文件中没有找到对应的 IP 地址,浏览器就会发出一个 DNS请求到本地DNS服务器 。本地DNS服务器一般是你的网络接入服务器商提供,比如中国电信,中国移动。
3、于是本地DNS服务器查看自己有没有缓存对应的 IP 地址,若有则直接返回结果,否则本地DNS服务器需要向DNS根服务器进行查询。根 DNS 服务器没有记录具体的域名和 IP 地址的对应关系,而是告诉本地 DNS 服务器,你可以到域服务器上去继续查询,并返回顶级域名服务器的 IP 地址给本地DNS 服务器。
4、本地DNS服务器再请求顶级域名服务器返回二级域名服务器IP,再请求二级域名服务器返回三级域名服务器IP…直到找到对应的 IP 地址,返回给浏览器。
5、最后,本地DNS服务器不仅要把IP地址返回给用户电脑,还要把这个对应关系保存在缓存中,以备下次别的用户查询时,可以直接返回结果,加快网络访问。
注:域服务器收到请求之后,不会直接返回域名和IP地址的对应关系,而是告诉本地DNS服务器,相关域名的DNS服务器的地址。
(图片转自第一篇参考文章)
域名的级别是指一个域名由多少级组成,域名的各个级别被"."分开,总而言之,有多少个点就是几级域名。
顶级域名在开头有一个点(.com .cn .net)
一级域名就是在"com cn net"前加一级 (baidu.com)
二级域名就是在一级域名前再加一级(www.baidu.com)
二级域名及以上级别的域名,统称为子域名,不在注册域名的范畴中
二、建立TCP连接
主要是三次握手:
(1)第一次握手:
客户端主动向服务端发送请求建立连接的报文,并进入同步已发送状态;SYN = 1 表示连接请求,seq = x 表示起始序列号,x表示一个随机数,通常为1。(SYN=1,seq=x)
(2)第二次握手:
服务端收到客户端的报文之后,返回一段确认接收到请求报文并同意创建新连接的报文,并进入同步收到状态。(SYN=1, ACK=1, seq=y, ack=x+1)
(3)第三次握手:
客户端接收到服务端的确认报文之后,也返回一段确认报文给服务端表示自己已收到确认报文并进入建立连接状态,服务端收到确认报文后也进入建立连接状态,此时双方成功建立TCP连接。(ACK=1, seq=x+1, ack=y+1)
(详解欢迎参考我的另一篇博客TCP三次握手、四次挥手过程详解)
三、客户端发送HTTP请求
浏览器将用户输入的地址封装成HTTP Request请求报文,发送到服务器。
HTTP请求报文格式:请求行+请求头+空行+请求体
GET / HTTP/1.1 //请求行:请求方法+HTTP版本
Accept:image/gif.image/jpeg //从这里开始直到空行都是请求头
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
Accept-Encoding:gzip,deflate
username=jinqiao&password=1234 //请求体
四、服务端返回资源
服务器收到请求后会返回响应报文,并在响应体中返回相关资源。
HTTP响应报文格式:状态行+响应头+空行+响应体
HTTP/1.1 200 OK //状态行:HTTP版本+状态码+提示信息
Server:Apache/r/n //从这里开始直到空行都是响应头
Content-Type:application/json
Content-Encoding:gzip/r/nxi
{"password": "1234","userName":"Tom"} //响应体
扩展问题:
(1)get和post的区别 传送门
(2)常见的状态码 传送门
(3)常见的请求头和响应头
(4)强缓存与协商缓存 传送门
五、浏览器渲染页面
(1)HTML被HTML解析器解析成DOM Tree, css则被css解析器解析成CSSOM Tree(并行解析)。
(2)DOM Tree和CSSOM Tree解析完成后,被合并到一起,形成渲染树(render Tree)。
(3)重排:节点信息计算,即根据渲染树计算每个节点的几何信息(大小及位置)。
(4)重绘:渲染绘制,即根据计算好的信息绘制整个页面,渲染出最终的页面。
扩展问题:
(1)重排和重绘,如何减少 传送门
(2)HTML代码执行的顺序和细节
六、断开TCP连接
主要是四次挥手:
(1)第一次挥手:
数据传输完毕,客户端想要释放连接(没有数据需要传输给服务端了),于是向服务端发送一段TCP报文请求释放连接,然后进入终止等待状态一。并且停止在客户端到服务端方向上发送数据,但是客户端仍然能接收从服务端传输过来的数据。FIN=1 表示请求释放连接, u为随机生成的起始报文段序号(FIN=1,seq=u)
(2)第二次挥手:
服务端收到连接释放报文,立即发出确认报文,表示接收到客户端发送的释放连接的请求,并进入关闭等待状态。(ACK=1,seq=v,ack=u+1)
(3)第三次挥手:
服务端自从发出ACK确认报文之后,经过了关闭等待阶段,做好了释放服务器端到客户端方向上的连接准备,再次向客户端发出一段TCP报文表示已经准备好释放连接了(没有数据需要传输给客户端了),然后进入最后确认状态。(FIN=1,ACK=1,seq=w,ack=u+1)
(4)第四次挥手:
客户端收到从服务器端发出的TCP报文,确认了服务器端已做好释放连接的准备,于是再次向服务端发送报文表示接收到服务端准备好释放连接的信号,并进入TIME-WAIT阶段等待2MSL ( 最大报文生存时间) 后再断开连接,服务端收到最终确认报文后立即断开连接,双方断开TCP连接。(ACK=1,seq=u+1,ack=w+1)
(详解欢迎参考我的另一篇博客TCP三次握手、四次挥手过程详解)