先上一张图给大家看看
相信看完这张图后大家对一次请求也有了大致的了解了,当前其中还有很多细节小编没有画出来,然后我们来看看部分过程的细节
所以其流程大致如下:
①:DNS解析域名得到IP地址
②:客户端与服务器建立连接(TCP三次握手)
③:客户端发起请求
④:服务器接收到请求根据端口号.路径等找到对应资源文件,响应源代码给客户端
⑤:客户端拿到请求到的数据(html页面的源代码),开始解析页面以及请求资源
⑥:客户端渲染页面
⑦:web服务器断开连接(四次挥手)
1.url的组成
说的url那就的说说URI和URN了,URI由URL和URN组成。
URI:统一资源标识符
URL:统一资源定位符
URN:统一资源名称
2.DNS解析过程
1、在浏览器中输入www . qq .com 域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析
2、如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析
3、如果hosts与本地DNS解析器缓存都没有相应的网址映射关系,首先会找TCP/ip参数中设置的首选DNS服务器,在此我们叫它本地DNS服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性
4、如果要查询的域名,不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性
5、如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至13台根DNS,根DNS服务器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负责.com域的这台服务器。这台负责.com域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com域的下一级DNS服务器地址(http://qq.com)给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找http://qq.com域服务器,重复上面的动作,进行查询,直至找到www . qq .com主机
6、如果用的是转发模式,此DNS服务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。不管是本地DNS服务器用是是转发,还是根提示,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机
3.TCP三次握手
第一次握手:客户端发送一个带 SYN=1,Seq=X 的数据包到服务器端口(第一次握手,由浏览器发起,告诉服务器我要发送请求了)
第二次握手服务器发回一个带 SYN=1, ACK=X 1, Seq=Y 的响应包以示传达确认信息(第二次握手,由服务器发起,告诉浏览器我准备接受了,你赶紧发送吧)
第三次握手:客户端再回传一个带 ACK=Y 1, Seq=Z 的数据包,代表“握手结束”(第三次握手,由浏览器发送,告诉服务器,我马上就发了,准备接受吧)
其实简单理解就是:
客户端问服务器:哥们,忙不?
服务器回客户端:不忙,哥们有活?
客户端回服务器:大活,准备接受吧!
4.TCP四次挥手
第一次挥手:发起方向被动方发送报文,Fin、Ack、Seq,表示已经没有数据传输了。并进入 FIN_WAIT_1 状态。(第一次挥手:由浏览器发起的,发送给服务器,我请求报文发送完了,你准备关闭吧)
第二次挥手:被动方发送报文,Ack、Seq,表示同意关闭请求。此时主机发起方进入 FIN_WAIT_2 状态。(第二次挥手:由服务器发起的,告诉浏览器,我请求报文接受完了,我准备关闭了,你也准备吧)
第三次挥手:被动方向发起方发送报文段,Fin、Ack、Seq,请求关闭连接。并进入 LAST_ACK 状态。(第三次挥手:由服务器发起,告诉浏览器,我响应报文发送完了,你准备关闭吧)
第四次挥手:发起方向被动方发送报文段,Ack、Seq。然后进入等待 TIME_WAIT 状态。被动方收到发起方的报文段以后关闭连接。发起方等待一定时间未收到回复,则正常关闭。(第四次挥手:由浏览器发起,告诉服务器,我响应报文接受完了,我准备关闭了,你也准备吧)
5.浏览器渲染过程
浏览器解析渲染页面分为一下五个步骤:
1.根据 HTML 解析出 DOM 树
2.根据 CSS 解析生成 CSS 规则树
3.结合 DOM 树和 CSS 规则树,生成渲染树
4.根据渲染树计算每一个节点的信息
5.根据计算好的信息绘制页面
根据 HTML 解析 DOM 树
根据 HTML 的内容,将标签按照结构解析成为 DOM 树,DOM 树解析的过程是一个深度优先遍历。即先构建当前节点的所有子节点,再构建下一个兄弟节点
在读取 HTML 文档,构建 DOM 树的过程中,若遇到 script 标签,则 DOM 树的构建会暂停,直至脚本执行完毕
根据 CSS 解析生成 CSS 规则树
解析 CSS 规则树时 js 执行将暂停,直至 CSS 规则树就绪
浏览器在 CSS 规则树生成之前不会进行渲染
结合 DOM 树和 CSS 规则树,生成渲染树
DOM 树和 CSS 规则树全部准备好了以后,浏览器才会开始构建渲染树
精简 CSS 并可以加快 CSS 规则树的构建,从而加快页面相应速度
根据渲染树计算每一个节点的信息(布局)
布局:通过渲染树中渲染对象的信息,计算出每一个渲染对象的位置和尺寸
回流:在布局完成后,发现了某个部分发生了变化影响了布局,那就需要倒回去重新渲染
根据计算好的信息绘制页面
绘制阶段,系统会遍历呈现树,并调用呈现器的“paint”方法,将呈现器的内容显示在屏幕上
重绘:某个元素的背景颜色,文字颜色等,不影响元素周围或内部布局的属性,将只会引起浏览器的重绘
回流:某个元素的尺寸发生了变化,则需重新计算渲染树,重新渲染
6.异步的请求
在web2.0时代,即使在页面渲染后客户端还是持续与服务器端通信,这个模式被称为AJAX,是“Asynchronous JavaScript And XML”的缩写
JS的解析是由浏览器中的JS解析引擎完成的。JS是单线程运行,也就是说,在同一个时间内只能做一件事,所有的任务都需要排队,前一个任务结束,后一个任务才能开始
但是又存在某些任务比较耗时,如IO读写等,所以需要一种机制可以先执行排在后面的任务,这就是:同步任务(synchronous)和异步任务(asynchronous)
JS的执行机制就可以看做是一个主线程加上一个任务队列(task queue)。同步任务就是放在主线程上执行的任务,异步任务是放在任务队列中的任务
所有的同步任务在主线程上执行,形成一个执行栈;异步任务有了运行结果就会在任务队列中放置一个事件;脚本运行时先依次运行执行栈,然后会从任务队列里提取事件,运行任务队列中的任务,这个过程是不断重复的,所以又叫做事件循环(Event loop)
浏览器在解析过程中,如果遇到请求外部资源时,请求过程是异步的,并不会影响HTML文档进行加载,但是当文档加载过程中遇到JS文件,HTML文档会挂起渲染过程,不仅要等到文档中JS文件加载完毕还要等待解析执行完毕,才会继续HTML的渲染过程。原因是因为JS有可能修改DOM结构,这就意味着JS执行完成前,后续所有资源的下载是没有必要的,这就是JS阻塞后续资源下载的根本原因。CSS文件的加载不影响JS文件的加载,但是却影响JS文件的执行。JS代码执行前浏览器必须保证CSS文件已经下载并加载完毕