浏览器工作原理2
浏览器工作原理2:
在浏览器工作原理1中讲解了浏览器工作原理的概括和http和https协议。这一章主要讲解两个过程:如何解析请求回来的HTML代码,DOM树又是如何构建的。
解析代码和DOM树:
浏览器在解析HTML文档时,会把HTML解析为一种文档对象模型的对象集合,简称DOM。先来简单说一下对象和树的概念。在HTML中,每一个元素都是一个对象实例,这些元素都有不同的属性,有的属性是我们在HTML中可以设定的,有的属性是浏览器解析HTML文档生成的。树是一种结构,也就是组织数据之间的关系。树是由一个一个的节点和它们之间有层次的关系组成的。和现实中的树有些相似,树都有一个根节点,但是计算机的树一般都是倒着画的,也就是说根是在最上面的,根节点下面可以有很多子节点,子节点下面也可以有更多的子节点,没有子节点的节点称为叶节点。上一级的节点称为父节点,一个节点只能有一个父节点。解析代码就是像构建DOM树一样把它一个节点一个节点的解析。
DOM树的构建:
DOM是文档对象模型的缩写,它是html文档的对象表示,作为html元素的外部接口供js等调用。和html一样,DOM的规范也是由W3C组织制定的。这是使用文档的一般规范。一个模型描述一种特定的html元素。这里所谓的树包括了DOM节点是说树是由实现了DOM接口的元素构建而成的。浏览器为html定制了专属的解析器。html5中描述了这个解析算法,算法包括两个阶段:符号化和构建树。
符号化是词法分析的过程,将输入解析为符号,html的符号包括开始标签、结束标签、属性名及属性值。符号识别器识别出符号后,将其传递给树构建器,并读取下一个字符,以识别下一个符号,这样直到处理完所有输入。
算法输出html符号,该算法用状态机表示。每次读取输入流中的一个或多个字符,并根据这些字符转移到下一个状态,当前的符号状态及构建树状态共同影响结果,这意味着,读取同样的字符,可能因为当前状态的不同,得到不同的结果以进入下一个正确的状态。这个算法很复杂,这里用一个简单的例子来解释这个原理。例-符号化下面的html:
```<html>
<body>
Hello world
</body>
</html>
```
初始状态为Data State,当遇到<字符,状态变为Tag open state,读取一个a-z的字符将产生一个开始标签符号,状态相应变为Tag name state,一直保持这个状态直到读取到>,每个字符都附加到这个符号名上,例子中创建的是一个html符号。
当读取到>,当前的符号就完成了,此时,状态回到Data state,重复这一处理过程。到这里,html和body标签都识别出来了。现在,回到Data state,读取Hello world中的字符H将创建并识别出一个字符符号,这里会为Hello world中的每个字符生成一个字符符号。
这样直到遇到<。现在,又回到了Tag open state,读取下一个字符/将创建一个闭合标签符号,并且状态转移到Tag name state,还是保持这一状态,直到遇到>。然后,产生一个新的标签符号并回到Data state。
总之就是很麻烦,看看就行了。
树的构建算法:
在树的构建阶段,将修改以Document为跟的DOM树,将元素附加到树上,每个由符号识别器识别生成的节点将会被树构造器进行处理,规范中定义了每个符号相对应的Dom元素,对应的Dom元素将会被创建,这些元素除了会被添加到Dom树上,还将被添加到开放元素堆栈中,这个堆栈用来纠正嵌套的未匹配和未闭合标签,这个算法也是用状态机来描述,所有的状态采用插入模式。 还用上面的代码来实例树的创建过程:
构建树这一阶段的输入是符号识别阶段生成的符号序列。首先是initial mode,接收到html符号将转换为before html模式,在这个模式中对这个符号进行再处理,此时,创建一个HTMLHtmlElement元素,并附加到根Documnet对象上。
状态此时变为before head,接收到body符号时,即使这里没有head符号,也将自动创建一个HTMLHeadElement元素并附加到树上,现在转到in head模式,然后是after head。到这里,body符号将会被再次处理,将创建一个HTMLBodyElement并插入到树中,同时转移到in body模式。
然后接收到字符串Hello word的字符符号,第一个字符将导致创建并插入一个text节点,其他字符将附加到该节点。
接收到body结束符号时,转移到after body模式,接着接收到html结束符号,这个符号意味着转移到了after after body模式,当接收到文件结束符时,整个解析过程结束。 这个比上面的符号化还要更难懂,看看知道就行了。