输入网址到网页呈现的全过程

我们通常访问一个网站后,到呈现网页到底发生了些什么呢?之间到底有哪些流程呢?今天我们来探索一下这个过程到底发生了什么。 文章分为6个点逐步探索。希望你能耐心阅读并有所收获。

1. 域名解析

首先,我们经常访问的网址 www.baidu.com 为例,其中www为主机,baidu为域名,com为类型。但是有网址不能直接找到对应的响应主机,必须把网址(域名)转化为ip地址。这一过程就叫做DNS解析(也叫做DNS查询)。

(1)首先了解一下DNS的结构:

(1)根域名服务器,全球(IPV4)只有13个不同ip地址的服务器,注意不是服务器只有13台,只是他们所代表的地址只有13个,也就是存在镜像服务器,一个地址可以对应多个镜像服务器。
(2)根域名服务器之下的顶级域名服务器,如com、net、cn、gov等。
(3)顶级域名服务器之下的权威服务器,比如baidu、facebook等。
(4)权威服务器之下的资源记录,比如www、ftp、mail等。

(2)查询的过程如下:

(1)首先会在浏览器缓存中去查询,之前每浏览一个网站,浏览器都会在缓存中存有域名与ip地址的映射关系。不过缓存失效的时间不由浏览器决定,而由操作系统决定。
(2)浏览器缓存中查询不到后,之后会在系统缓存中查询,由浏览器发起一个系统调用,查询系统缓存中的数据。
(3)系统缓存中也查询不到后,将会去路由器缓存中查找。
(4)路由器缓存中也找不到的话,将会从本地DNS服务器的缓存中查找,本地服务器即用户自己配置的DNS服务器。
(5)如果本地的DNS服务器也找不到的话,本地DNS将会发送请求至根域名服务器,根域名服务器中没有相关缓存数据的时候,就会返回com顶级域名服务器的地址。然后本地DNS服务器再发送请求至com顶级域名服务器,com顶级域名服务器中查询不到的话,就会返回baidu权威服务器的地址,然后本地DNS服务器再发送请求至baidu权威服务器,baidu权威服务器就会返回www主机地址。(这是一种迭代的过程,还有一种递归的过程。即local至根域名,根域名不直接返回com地址,而是发送请求至com,com发送请求至baidu,baidu发送请求至www,www再返回给baidu,baidu返回给com,com再返回给local)至此,整个DNS查询步骤结束,现在浏览器拿到了域名对应的ip地址返回给本地域名服务器;

2. TCP的三次挥手

浏览器发送请求至服务器,输入的地址是www.baidu.com,那么浏览器默认将网址改成http://www.baidu.com。然后浏览器客户端会与服务器建立TCP连接进行三次握手:
(1)第一次握手:建立连接时,客户端发送SYN包至服务器,并进入SYN_SENT状态,等待服务器确认
(2)第二次握手:服务器收到客户端的SYN包,如同意连接,发送一个ACK,同时发送自己的SYN,此时服务器进入SYN_RCVD状态
(3)第三次握手:客户端接收到服务器发送的SYN+ACK后,进入ESTABLISHED状态,并发送服务器SYN包的确认ACK,服务器接收到客户端ACK后,进入ESTABLISHED状态
(4)当客户端和服务器都进入ESTABLISHED状态后,客户端和服务器之间就可以开始双向传递数据了。

图解如下:


三次握手.png

3. 浏览器发送http请求

浏览器构建http请求报文,并通过TCP协议传送到服务器的指定端口。http请求报文一共包括三个部分:
请求行:指定http请求的方法、url、http协议版本等
请求头:描述浏览器的相关信息,语言、编码等。如下
请求正文:当发送POST, PUT,GET等请求时,通常需要向服务器传递数据。这些数据就储存在请求正文中。

发送请求图例:


image.png

大概介绍上面图中几个字段:
(1)Request Method表明请求方式是get。
(2)User-Agent,用户代理,表明所用浏览器的一些信息,包括内核,版本等。
(3)Connection:keep-alive表明需要服务器为之后的请求保持tcp连接
(4)Cookie中保存了一些与用户状态相关的数值,可以与session连用来跟踪会话,那么有关cookie与session的内容,可以自行查阅Cookie与Session的区别。

4. 服务器http请求响应

服务器处理http请求,并返回响应报文。HTTP响应报文由四部分组成:响应行、响应头、空行、响应体
一、响应行:响应行一般由协议版本、状态码及其描述组成
二、响应头:响应头用于描述服务器的基本信息,以及数据的描述,服务器通过这些数据的描述信息,可以通知客户端如何处理等一会儿它回送的数据。
常见的响应头字段含义:
(1) Allow:服务器支持哪些请求方法(如GET、POST、PUT等)。
(2) Content-Encoding:文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE4、IE5才支持它。因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader(“Accept- Encoding”))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。
(3) Content-Length:表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果你想要利用持久连接的优势,可以把输出文档写入 ByteArrayOutputStram,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。
(4) Content- Type:表示后面的文档属于什么MIME类型。Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置 Content-Type,因此HttpServletResponse提供了一个专用的方法setContentType。
(5) Date:当前的GMT时间,例如,Date:Mon,31Dec200104:25:57GMT。Date描述的时间表示世界标准时,换算成本地时间,需要知道用户所在的时区。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。
(6) Expires:告诉浏览器把回送的资源缓存多长时间,-1或0则是不缓存。
(7) Last-Modified:文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置。
(8) Location:这个头配合302状态码使用,用于重定向接收者到一个新URI地址。表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。
(9) Refresh:告诉浏览器隔多久刷新一次,以秒计。
(10)Server:服务器通过这个头告诉浏览器服务器的类型。Server响应头包含处理请求的原始服务器的软件信息。此域能包含多个产品标识和注释,产品标识一般按照重要性排序。Servlet一般不设置这个值,而是由Web服务器自己设置。
(11)Set-Cookie:设置和页面关联的Cookie。Servlet不应使用response.setHeader(“Set-Cookie”, …),而是应使用HttpServletResponse提供的专用方法addCookie。
(12)Transfer-Encoding:告诉浏览器数据的传送格式。
(13)WWW-Authenticate:客户应该在Authorization头中提供什么类型的授权信息?在包含401(Unauthorized)状态行的应答中这个头是必需的。例如,response.setHeader(“WWW-Authenticate”, “BASIC realm=\”executives\”“)。注意Servlet一般不进行这方面的处理,而是让Web服务器的专门机制来控制受密码保护页面的访问。
注意:设置应答头最常用的方法是HttpServletResponse的setHeader,该方法有两个参数,分别表示应答头的名字和值。和设置状态代码相似,设置应答头应该在发送任何文档内容之前进行。
setDateHeader方法和setIntHeader方法专门用来设置包含日期和整数值的应答头,前者避免了把Java时间转换为GMT时间字符串的麻烦,后者则避免了把整数转换为字符串的麻烦。
HttpServletResponse还提供了许多设置,如下:
setContentType:设置Content-Type头。大多数Servlet都要用到这个方法。
setContentLength:设置Content-Length头。对于支持持久HTTP连接的浏览器来说,这个函数是很有用的。
addCookie:设置一个Cookie(Servlet API中没有setCookie方法,因为应答往往包含多个Set-Cookie头)。
三、空行:最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头;
四、响应体:响应体就是响应的消息体,如果是纯数据就是返回纯数据,如果请求的是HTML页面,那么返回的就是HTML代码,如果是JS就是JS代码,如此之类。

响应请求图例如下:


image.png

5. 文件渲染

整个渲染的过程其实就是将http请求的各种资源,通过浏览器渲染引擎的解析,输出可视化的图像。
基本过程图解如下:


image.png

渲染过程:


image.png

从图中可以看出,一个渲染引擎大致包括HTML解释器、CSS解释器、布局和JavaScript引擎。
(1)HTML解释器:解释HTML语言的解释器,本质是将HTML文本解释成DOM树(文档对象模型)。
(2)CSS解释器:解释样式表的解释器,其作用是将DOM中的各个元素对象加上样式信息,从而为计算最后结果的布局提供依据。

(3)布局:将DOM和css样式信息结合起来,计算它们的大小位置等布局信息,形成一个能够表示这所有信息的内部表示模型即渲染树。
(4)JavaScript引擎:JavaScript可以修改网页的内容,也能修改CSS的信息,JavaScript引擎解释JavaScript代码并把代码的逻辑和对DOM和CSS的改动信息应用到布局中去,从而改变渲染的结果。
(5)这些模块依赖很多其他的基础模块,这其中包括网络,存储,2D/3D图形,音频视频和图片解码器等。实际上,渲染引擎中还应该包括如何使用这些依赖模块的部分,这部分的工作其实并不少,因为需要使用它们来高效的渲染网页。例如,利用2D/3D图形库来实现高性能的网页绘制和网页的3D渲染,这个实现非常非常的复杂。最后,当然,在最下面,依然少不了操作系统的支持,例如线程支持,文件支持等等。

浏览器是如何完成网页渲染?
1.解析HTML文件,创建DOM树
2.解析CSS,形成CSS对象模型
3.将CSS与DOM合并,构建渲染树(renderingtree)
4.布局和绘制(重绘、重排)

重绘:重绘是改变不影响元素在网页中的位置的元素样式时,譬如background-color(背景色), border-color(边框色), visibility(可见性),浏览器会根据元素的新属性重新绘制一次(这就是重绘,或者说重新构造样式),使元素呈现新的外观。重绘不会带来重新布局,所以并不一定伴随重排。

重排:渲染对象在创建完成并添加到渲染树时,并不包含位置和大小信息。计算这些值的过程称为布局或重排。当改变影响到文本内容或结构,或者元素位置时,重排或者说重新布局就会发生。这些改变通常由以下事件触发: DOM操作(元素添加、删除、修改或者元素顺序的改变)、内容变化,包括表单域内的文本改变、CSS属性的计算或改变、添加或删除样式表、更改“类”的属性、浏览器窗口的操作(缩放,滚动)、伪类激活(悬停)。

总括:"重绘"不一定需要"重排",比如改变某个网页元素的颜色,就只会触发"重绘",不会触发"重排",因为布局没有改变。但是,"重排"必然导致"重绘",比如改变一个网页元素的位置,就会同时触发"重排"和"重绘",因为布局改变了。

浏览器如何优化渲染?
(1)将多次改变样式属性的操作合并成一次操作
(2)将需要多次重排的元素,position属性设为absolute或fixed,这样此元素就脱离了文档流,它的变化不会影响到其他元素。例如有动画效果的元素就最好设置为绝对定位。
(3)由于display属性为none的元素不在渲染树中,对隐藏的元素操作不会引发其他元素的重排。如果要对一个元素进行复杂的操作时,可以先隐藏它,操作完成后再显示。这样只在隐藏和显示时触发2次重排。
看这个的时候又想到display:none、visibility:hidden和overflow:hidden的区别,这个问题自行查阅(https://www.cnblogs.com/yangjie-space/p/4857654.html)。

6. 四次挥手(断开TCP请求)

第一次挥手:主动关闭方发送一个FIN并进入FIN_WAIT1状态。
第二次挥手:被动关闭方接收到主动关闭方发送的FIN并发送ACK,此时被动关闭方进入CLOSE_WAIT状态;主动关闭方收到被动关闭方的ACK后,进入FIN_WAIT2状态。
第三次挥手:被动关闭方发送一个FIN并进入LAST_ACK状态。
第四次挥手:主动关闭方收到被动关闭方发送的FIN并发送ACK,此时主动关闭方进入TIME_WAIT状态,经过2MSL时间后关闭连接;被动关闭方收到主动关闭方的ACK后,关闭连接。

图解如下:


四次挥手.png

总结:以上就是在浏览器中输入一个网址到网页呈现的全过程,细细追究其中,其实发生了很多事情,文章比较长,希望你能耐心看完并有所收获,当然也很开心你能看到这儿,如你有更好的方式方法,请留言告知,相互学习才能更快进步.

优秀文章推荐:
https://blog.csdn.net/qq_33591903/article/details/84246177
https://www.cnblogs.com/xz233/p/13603975.html
https://blog.csdn.net/a19881029/article/details/30241561
https://blog.csdn.net/osdfhv/article/details/52159341

你可能感兴趣的:(输入网址到网页呈现的全过程)