从输入url到浏览器显示页面发生了什么
当在浏览器地址栏输入网址,如:www.XXX.com后浏览器是怎么把最终的页面呈现出来的呢?
㈠经历的步骤
★第一部分:网络通信
⑴在浏览器中输入url
⑵应用层DNS解析域名
⑶应用层客户端发送HTTP请求
⑷传输层TCP传输报文
⑸网络层IP协议查询MAC地址
⑹数据到达数据链路层
⑺服务器接收数据
⑻服务器响应请求
⑼服务器返回相应文件
★第二部分:页面渲染
㈡涉及基本知识点
第一部分:计算机网络
⑴五层因特尔协议栈:
①应用层(dns、http):DNS解析成IP并完成http请求发送;
②传输层(tcp、udp):三次握手四次挥手模式建立tcp连接;
③网络层(IP、ARP):IP寻址;
④数据链路层(PPP):将请求数据封装成帧;
⑤物理层:利用物理介质传输比特流(传输的时候通过双绞线、电磁波等)
OIS七层框架:多了两层即,会话层(处理两个通信系统中交换信息的表示方式)和表示层(管理不同用户和进程之间的对话)。
⑵get和post的区别:
①get产生一个tcp数据包,post产生两个
②get请求时会把headers和data数据一起发送出去;
③post请求时,浏览器先发送headers,服务器100继续,浏览器再发送data。
⑶DNS查询得到IP
①请求信息:首先查看域名的本地DNS缓存,该缓存存储计算机最近检索到的信息,如果计算机不知道答案,那么就需要执行一个DNS查询来查找答案;
②询问递归式DNS服务器:
☀如果信息不存储在本地,计算机会联系您的ISP(网络提供商)的递归DNS服务器;
☀这些专用计算机会为你执行一个DNS查询工作;
☀递归服务器有自己的缓存,所以这个查询过程通常在这里完成,并将信息还回给用户;
③询问根域名服务器
☀如果递归服务器没有答案,他们会查询根域名服务器;
☀根域名服务器是一种计算机,它扮演着一种DNS的电话接线员的角色,他们不知道答案,但可以将我们的疑问指向知道在哪里可以找到答案的人。
④询问TLD域名服务器:
☀根域名服务器将查看请求的第一部分,按从右到左的顺序,从www.dyn.com中找到.com,并将请求指向.com对应的顶级域名服务器(TLD).com;
☀每个TLD,如(.com,.org,.us)都有自己的顶级域名服务器,
☀这些服务器没有我们需要的信息,但他们可以直接将我们引导到有信息的服务器。
⑤询问权威的DNS服务器
☀TLD域名服务器会继续检查请求的下一部分(dyn)www.dyn.com,并将查询指向负责此特定域名的服务器;
☀这些权威的服务器将负责了解关于特定域的所有信息,并将信息存储在DNS记录。
⑥找回记录:
-递归服务器从权威服务器中检索dyn.com的记录,并将记录存储在本地缓存;
☀如果其他任何人请求dyn.com的主机记录,递归服务器已经有答案了,并不需要再次进行查找;
☀所有记录都有一个期限,一段时间后,递归服务器将需要要求一个新的记录副本,以确保信息不回过时。
⑦接收答案:
☀有了答案,递归服务器将记录返回到计算机,
☀您的计算机将记录存储在缓存中,从记录中读取IP地址,然后将这些信息传递给浏览器;
☀然后浏览器就可以根据IP地址和服务器进行连接建立。
⑷TCPIP请求
①http的本质就是TCPIP请求;
②需要经历3次握手建立连接,4次挥手断开连接;
③TCP将http长报文划分为短报文,通过三次握手与服务器端建立连接,进行可靠传输。
★三次握手:
⒈客户端:你是XXX服务端吗?
⒉服务端: 我是XXX服务端,你是客户端吗?
⒊客服端: 是的,我是客户端
⒋建立连接成功后,接下来就可以进行正式的传输数据。
★四次挥手断开连接
⒈主动方:我已经关闭了向你那边的信息发送通道,只能被动接受信息了;
⒉被动方: 收到通道关闭的信息;
⒊被动方: 我现在也关闭了向你那边发送信息的通道
⒋主动方: 左后收到信息,连接断开,之后双方无法通信
⑸TCP/IP的并发限制:
①浏览器对同一个域名下并发的TCP连接是有限制的(2-10个不等)
②而且在http1.0中往往一个资源的下载就需要一个tcp/ip请求
第二部分:浏览器机制
⑴进程和线程的概念
①进程是CPU资源分配的最小单位,是能拥有资源和独立运行的最小单位;
②线程是CPU调度的最小单位,线程是建立在进程的基础上的一次程序运行单位,一个进程可以拥有多个线程;
③通俗的讲:进程是一个工厂,工厂有它独立的资源,工厂之间相互独立->进程之间相互独立,线程是工厂中的工人,多个工人之间可以协作完成任务,工厂内有一个或多个工人,工人之间共享空间。
⑵多进程的浏览器
浏览器是多进程的,有一个主控进程,以及每一个tab页面都会开一个进程(某些情况下多个tab由于优化策略会合并)
★浏览器主要进程:
①Browser进程:浏览器的主进程,负责协调、主控,只有一个,作用:
☀负责浏览器界面的显示、与用户交互(如前进、后退等)
☀负责各个页面的管理,创建和销毁其他进程;
☀将Renderer进程得到的内存中的Bitmap绘制到用户界面上
☀网络资源的管理和下载等
②第三方插件进程: 每种类型的插件对应一个进程,仅当该插件使用时才创建;
③GPU进程: 最多一个,用于3D绘制等;
④浏览器渲染进程(Renderer进程、浏览器内核、内部是多线程):
☀默认没打开一个tab页面,就会启动一个Renderer进程;
☀负责页面的渲染,脚本的执行,事件的处理。
★浏览器多进程的优势
①避免单个page crash影响整个浏览器;
②避免第三方插件crash影响整个浏览器
③多进程充分利用多核优势;
④方便使用沙盒模型隔离插件等进程,提高浏览器稳定性
第三部分:浏览器内核(渲染进程)
浏览器渲染进程内部是多线程,包含主要线程有:
⑴GUI渲染线程:
①负责浏览器界面的渲染,解析HTML、CSS,构建DOM树和RenderObject树,布局和绘制等;
②当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时该线程会执行;
注意:GUI渲染线程和JS引擎线程是互斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会保存在一个队列中等JS引擎空闲时立即执行。
⑵JS引擎线程
①JS内核,负责处理JavaScript脚本程序(V8引擎)
②负责解析JavaScript脚本,运行代码;
③JS引擎一直等待着任务队列中的任务到来,然后加以处理,一个tab页面(renderer进程)中无论什么时候都只有一个JS线程在运行JS程序;
注意:由于GUI渲染线程和JS引擎线程是互斥的,所以如果JS程序运行时间过长,这样会导致页面渲染不连贯,导致页面渲染加载阻塞;
⑶事件触发线程:
①归属于浏览器,而不是JS引擎,用来控制事件循环;
②当JS引擎执行代码块如setTimeOut时(也可以来自浏览器内核的其他线程,如鼠标单击事件、AJAX异步请求等),会将对应的任务添加到事件线程中;
③当对应的事件符合触发条件被触发时,该线程就会把事件添加到JS的待处理队列的队尾,等待JS引擎的处理;
注意:由于JS的单线程的关系所以这些待处理队列中的事件都得排队等待JS引擎处理(当JS引擎空闲时才会去执行)。
⑷定时触发器线程:
①setTimeOut与setInterval所在的线程;
②浏览器的定时计数器并不是由JavaScript引擎计数的,(因为JavaScript是单线程,如果处于阻塞状态就会影响计时的准确)因此通过单独的线程来计时并触发定时(计时完毕后,添加到事件队列,等待JS引擎空闲时执行)
⑸异步http请求线程:
①在XMLHttpRequest在连接后是通过浏览器新开一个线程请求的
②将检测到状态变更时,如果设置有回调函数,异步线程就将产生状态变更事件,将这个回调在放到事件队列中,再由JavaScript引擎执行。
以下内容转自:https://www.cnblogs.com/kongxy/p/4615226.html
㈢步骤详细解释
第一部分:网络通信
互联网内各网络设备间的通信都遵循TCP/IP协议,利用TCP/IP协议族进行网络通信时,会通过分层顺序与对方进行通信。分层由高到低分别为:应用层、传输层、网络层、数据链路层。发送端从应用层往下走,接收端从数据链路层网上走。如图所示:
⑴在浏览器中输入url
用户输入url,例如http://www.baidu.com。其中http为协议,www.baidu.com为网络地址,及指出需要的资源在那台计算机上。一般网络地址可以为域名或IP地址,此处为域名。使用域名是为了方便记忆,但是为了让计算机理解这个地址还需要把它解析为IP地址。
⑵应用层DNS解析域名
①客户端先检查本地是否有对应的IP地址,若找到则返回响应的IP地址。若没找到则请求上级DNS服务器,直至找到或到根节点。
②DNS中递归查询和迭代查询的区别:
☀递归查询: 一般客户机和服务器之间属递归查询,即当客户机向DNS服务器发出请求后,若DNS服务器本身不能解析,则会向另外的DNS服务器发出查询请求,得到结果后转交客户机。
☀迭代查询(反复查询): 一般DNS服务器之间属迭代查询,如:若DNS2不能响应DNS1的请求,则它会将DNS3的IP给DNS2,以便其再向DNS3发出请求。
以一个DNS请求解析为例:
1)用户发起域名请求到dnsA,这时dnsA有这个记录,将结果返回给用户,这个过程是递归查询。
2)用户发起域名请求到dnsA,这时dns没有这个记录,它去向dnsB问有没有这个记录,以此类推,直到把结果返回给用户,这个过程是递归查询。
3)用户发起域名请求到dnsA,这时dnsA没有这个记录,它告诉用户,我没有这个记录,你去问dnsB吧,这个过程是迭代查询。
⑶应用层客户端发送HTTP请求
HTTP请求包括请求报头和请求主体两个部分,其中请求报头包含了至关重要的信息,包括请求的方法(GET / POST)、目标url、遵循的协议(http / https / ftp…),返回的信息是否需要缓存,以及客户端是否发送cookie等。
⑷传输层TCP传输报文
①位于传输层的TCP协议为传输报文提供可靠的字节流服务。它为了方便传输,将大块的数据分割成以报文段为单位的数据包进行管理,并为它们编号,方便服务器接收时能准确地还原报文信息。TCP协议通过“三次握手”等方法保证传输的安全可靠。
②三次握手”的过程是,发送端先发送一个带有SYN(synchronize)标志的数据包给接收端,在一定的延迟时间内等待接收的回复。接收端收到数据包后,传回一个带有SYN/ACK标志的数据包以示传达确认信息。接收方收到后再发送一个带有ACK标志的数据包给接收端以示握手成功。在这个过程中,如果发送端在规定延迟时间内没有收到回复则默认接收方没有收到请求,而再次发送,直到收到回复为止。
1)第一次握手:主机A发送位码为syn=1,随机产生seq number=x的数据包到服务器,客户端进入SYN_SEND状态,等待服务器的确认;主机B由SYN=1知道,A要求建立联机;
2)第二次握手:主机B收到请求后要确认联机信息,向A发送ack number(主机A的seq+1),syn=1,ack=1,随机产生seq=y的包,此时服务器进入SYN_RECV状态;
3)第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack number(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功。客户端和服务器端都进入ESTABLISHED状态
⑸网络层IP协议查询MAC地址
IP协议的作用是把TCP分割好的各种数据包传送给接收方。而要保证确实能传到接收方还需要接收方的MAC地址,也就是物理地址。IP地址和MAC地址是一一对应的关系,一个网络设备的IP地址可以更换,但是MAC地址一般是固定不变的。ARP协议可以将IP地址解析成对应的MAC地址。当通信的双方不在同一个局域网时,需要多次中转才能到达最终的目标,在中转的过程中需要通过下一个中转站的MAC地址来搜索下一个中转目标。
⑹数据到达数据链路层
在找到对方的MAC地址后,就将数据发送到数据链路层传输。这时,客户端发送请求的阶段结束
⑺服务器接收数据
接收端的服务器在链路层接收到数据包,再层层向上直到应用层。这过程中包括在运输层通过TCP协议讲分段的数据包重新组成原来的HTTP请求报文。
⑻服务器响应请求
服务接收到客户端发送的HTTP请求后,查找客户端请求的资源,并返回响应报文,响应报文中包括一个重要的信息——状态码。状态码由三位数字组成,其中比较常见的是200 OK表示请求成功。301表示永久重定向,即请求的资源已经永久转移到新的位置。在返回301状态码的同时,响应报文也会附带重定向的url,客户端接收到后将http请求的url做相应的改变再重新发送。404 not found 表示客户端请求的资源找不到。
⑼服务器返回相应文件
请求成功后,服务器会返回相应的HTML文件。接下来就到了页面的渲染阶段了。
第二部分:页面渲染
⑴现代浏览器渲染页面的过程是这样的:jiexiHTML以构建DOM树 –> 构建渲染树 –> 布局渲染树 –> 绘制渲染树。
⑵DOM树是由HTML文件中的标签排列组成,渲染树是在DOM树中加入CSS或HTML中的style样式而形成。渲染树只包含需要显示在页面中的DOM元素,像<head>元素或display属性值为none的元素都不在渲染树中。
⑶在浏览器还没接收到完整的HTML文件时,它就开始渲染页面了,在遇到外部链入的脚本标签或样式标签或图片时,会再次发送HTTP请求重复上述的步骤。在收到CSS文件后会对已经渲染的页面重新渲染,加入它们应有的样式,图片文件加载完立刻显示在相应位置。在这一过程中可能会触发页面的重绘或重排。
参考:https://segmentfault.com/a/1190000014872028
https://www.cnblogs.com/yuanzhiguo/p/8119470.html
http://www.360doc.com/content/17/0330/14/11277047_641420560.shtml