面试题------一个网页如何解析的?"/>
经典面试题------一个网页如何解析的?
输入一个URL后会发生什么?
我们假定这个URL为a.com/1.php
简略版
首先,输入URL并敲下回车之后,即向服务器请求我们要的内容,先判断输入的是否是一个合法的URL,并且根据你输入的内容进行自动完成、字符编码等操作。
浏览器先通过系统缓存查找本地hosts文件,检测其中是否有对应关系,若有,则直接向对应IP发送请求,若没有将查询发往路由器,没有则通过DNS服务器来将域名解析成对应IP。
拿到服务器IP后,就到了TCP连接这里。
应用层开始发送HTTP请求(请求的内容为网站根目录下的1.php文件),浏览器会开始构造这样一个 HTTP 请求报文
传输层会发起一条到达服务器的 TCP 连接,这里涉及到TCP的三次握手(SYN,ACK/SYN,ACK),为了方便传输,会对数据进行分割(以报文段为单位),并标记编号,方便服务器接受时能够准确地还原报文信息,
网络层将数据段打包,并加入源及目标的IP地址,并且负责寻找传输路线。
判断目标地址是否与当前地址处于同一网络中,是的话直接根据 Mac 地址发送,否则使用路由表查找下一跳地址,以及使用 ARP 协议查询它的 Mac 地址。
链路层则通过以太网协议进行寻找对应的服务器。
服务器收到后,在自己的管理目录下找到相应文件,并将它交给web应用服务器处理(这里以apache为例)
web应用服务器接收并打开php文件,在php文件中通过对数据库连接的代码来连接本机或者网络上其他机器上的数据库,并在php程序中通过执行标准的SQL查询语句来获取数据库中的数据,再通过web应用服务器将数据生成html静态代码,并将html静态代码交还给服务器,然后返回HTTP响应
接着是关闭连接,浏览器解析:DOM构造,布局以及绘制页面,最终返回可视化网页
详细版
URL 解析
详细可以访问链接
-
地址解析
首先判断你输入的是一个合法的 URL 还是一个待搜索的关键词,并且根据你输入的内容进行自动完成、字符编码等操作
-
HSTS
安全隐患,会使用 HSTS 强制客户端使用 HTTPS 访问页面。
-
其他
浏览器还会进行一些额外的操作,比如安全检查、访问限制
-
检查缓存
DNS 查询
大致如图
-
浏览器缓存
浏览器会缓存DNS记录一段时间。有趣的是,操作系统没有告诉浏览器储存DNS记录的时间,这样不同浏览器会储存个自固定的时间(2分钟到30分钟不等)。 -
系统缓存
如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用。操作系统检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。 -
路由器缓存
如果hosts里没有这个映射,则将查询请求发向路由器,他一般会有自己的DNS缓存,如果缓存中有这个网址的映射关系,则直接返回,完成域名解析。 -
ISP DNS(本地DNS服务器)将请求发至根域名服务器,
如果上述缓存都没有相应的网址映射关系,首先会找TCP/IP参数中设置的首选DNS服务器(ISP的DNS),在此我们叫它本地DNS服务器,此服务器收到查询时,如果要查询的域名包含在本地配置区域资源中,则返回解析结果,完成域名解析。
如果要查询的域名不由本地DNS服务器区域解析,但该服务器缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析。 -
递归搜索
如果本地DNS服务器解析失败,则将请求发送至根DNS服务器,从根DNS服务器开始进行递归搜索。根DNS服务器收到请求后会判断这个域名(.com)是由谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负责.com域的这台服务器,这台负责.com域的服务器收到请求后,如果自己无法解析,就会找一个管理.com域的下一级DNS服务器地址给本地域名服务器。当本地DNS服务器收到这个地址后,就会通过地址找这个域服务器,重复上面的动作,进行查询,直至找到对应主机,最终将结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。
TCP连接
传输层会发起一条到达服务器的 TCP 连接,这里涉及到TCP的三次握手(SYN,ACK/SYN,ACK),为了方便传输,会对数据进行分割(以报文段为单位),并标记编号,方便服务器接受时能够准确地还原报文信息,
网络层将数据段打包,并加入源及目标的IP地址,并且负责寻找传输路线。
判断目标地址是否与当前地址处于同一网络中,是的话直接根据 Mac 地址发送,否则使用路由表查找下一跳地址,以及使用 ARP 协议查询它的 Mac 地址。
链路层则通过以太网协议进行寻找对应的服务器。
处理请求
即web服务器监听到请求,然后处理接受 TCP 报文后,会对连接进行处理,对HTTP协议进行解析(请求方法、域名、路径等),并且进行一些验证
接受响应
浏览器接收到来自服务器的响应资源后,会对资源进行分析。
首先查看 Response header,根据不同状态码做不同的事(比如上面提到的重定向)。
如果响应资源进行了压缩(比如 gzip),还需要进行解压。
然后,对响应资源做缓存。
接下来,根据响应资源里的 MIME 类型去解析响应内容(比如 HTML、Image各有不同的解析方式)。
处理请求和接收响应部分需要对http协议有比较深入的了解
渲染页面
步骤并不一定一次性顺序完成。如果 DOM 或 CSSOM 被修改,以上过程需要重复执行,这样才能计算出哪些像素需要在屏幕上进行重新渲染。实际页面中,CSS 与 JavaScript 往往会多次修改 DOM 和 CSSOM
- DOMTree构建
DOM全称为文档对象模型Document Object Model,其中一个DOM节点对应一个标签,Dom树即表示了HTML的文档结构
解码:浏览器从磁盘或网络读取HTML的原始字节,然后根据指定的文件编码格式(例如 UTF-8)将其转换为相应字符
令牌化:浏览器把字符转化成W3C HTML5 标准指定的各种确切的令牌,比如""、""以及其他在尖括号内的字符串。每个令牌都有特殊的含义以及它自己的一套规则,Token中会标注出当前的Token是开始标签
,还是结束标签
,或者文本标签
等。
词法分析:生成的令牌转化为对象,这个对象定义了它们的属性及规则,浏览器会根据Tokens里记录的开始标签
,结束标签
,将Tokens之间相互串联起来*(带有结束标签的Token不会生成Node)*。Node包含了这个节点的所有属性。例如<img src="xxx.png" >
标签最终生成出的节点对象中会保存图片地址等信息。
DOM树构建:最后,由于HTML标记定义了不同标签之间的关系(某些标签嵌套在其他标签中),创建的对象在树状的数据结构中互相链接,树状数据结构也捕获了原始标签定义的父子关系:HTML对象是body对象的父对象,body是p对象的父对象等等,如上面图所示
- CSSOMTree构建
CSSOM全称为CSS对象模型CSS Object Model,CSSOM告诉了浏览器元素在渲染时是什么样的。与HTML一样,我们需要将收到的 CSS 规则转换为浏览器可以理解、能够处理的东西
处理结果类似于
脚本处理:
浏览器解析文档,当遇到<script>
标签的时候,会立即解析脚本,停止解析文档(因为JS可能会改动DOM和CSS,所以继续解析会造成浪费)。
如果脚本是外部的,会等待脚本下载完毕,再继续解析文档。现在可以在script标签上增加属性 defer
或者async
。脚本解析会将脚本中改变DOM和CSS的地方分别解析出来,追加到DOM Tree和Style Rules上
PS:DOM和CSSOM是两个独立的过程,解析顺序一般是把CSS放前面,js放后面以提高效率
- Render Tree构建
DOM 树上每一个节点对应着网页里每一个元素,CSSOM树上每个节点对应着网页里每个元素的样式,并且此时浏览器也可以通过 JavaScript 操作DOM/CSSOM树,动态改变它的结构。但是DOM/CSSOM树本身并不能直接用于排版和渲染,浏览器还会生成另外一棵树:Render树,实际上就是一个计算好样式,与HTML对应的(包括哪些显示,那些不显示)
类似于
不包括Header 、 script 、meta 等不可见的节点
某些通过 CSS 隐藏的节点在渲染树中也会被忽略,比如应用了 display:none 规则的节点,而visibility: hidden只是视觉不可见,仍占据空间,不会被忽略
- 布局
计算这些节点在设备视口内的确切位置和大小
类似
- 渲染
系统会遍历呈现树,并调用呈现器的“paint”方法,将呈现器的内容显示在屏幕上。绘制工作是使用用户界面基础组件完成的。这之后就能看到想看的网页了
参考链接1
参考链接2
参考链接3
参考链接4
参考链接5
更多推荐
经典面试题------一个网页如何解析的?
发布评论