我的编程空间,编程开发者的网络收藏夹
学习永远不晚

输入URL后页面会发生什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

输入URL后页面会发生什么

这篇文章主要介绍“输入URL后页面会发生什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“输入URL后页面会发生什么”文章能帮助大家解决问题。

构建 DOM 树

由于浏览器无法直接理解 HTML字符串 ,因此将这一系列的字节流转换为一种有意义并且方便操作的数据结构,这种数据结构就是DOM树DOM树本质上是一个以document为根节点的多叉树。

那通过什么样的方式来进行解析呢?

HTML文法的本质

首先,我们应该清楚把握一点: HTML 的文法并不是上下文无关文法

这里,有必要讨论一下什么是上下文无关文法

在计算机科学的编译原理学科中,有非常明确的定义:

若一个形式文法G = (N, Σ, P, S) 的产生式规则都取如下的形式:V-&w,则叫上下文无关语法。其中 V∈N ,w∈(N∪Σ)* 。

其中把 G = (N, Σ, P, S) 中各个参量的意义解释一下:

  1. N 是非终结符(顾名思义,就是说最后一个符号不是它, 下面同理)集合。

  2. Σ 是终结符集合。

  3. P 是开始符,它必须属于 N ,也就是非终结符。

  4. S 就是不同的产生式的集合。如 S -> aSb 等等。

通俗一点讲,上下文无关的文法就是说这个文法中所有产生式的左边都是一个非终结符。

看到这里,如果还有一点懵圈,我举个例子你就明白了。

比如:

A -> B

这个文法中,每个产生式左边都会有一个非终结符,这就是上下文无关的文法。在这种情况下,xBy一定是可以规约出xAy的。

我们下面看看看一个反例:

aA -> BAa -> B

这种情况就是不是上下文无关的文法,当遇到B的时候,我们不知道到底能不能规约出A,取决于左边或者右边是否有a存在,也就是说和上下文有关。

关于它为什么是非上下文无关文法,首先需要让大家注意的是,规范的 HTML 语法,是符合上下文无关文法的,能够体现它非上下文无关的是不标准的语法。在此我仅举一个反例即可证明。

比如解析器扫描到form标签的时候,上下文无关文法的处理方式是直接创建对应 form 的 DOM 对象,而真实的 HTML5 场景中却不是这样,解析器会查看 form 的上下文,如果这个 form 标签的父标签也是 form, 那么直接跳过当前的 form 标签,否则才创建 DOM 对象。

常规的编程语言都是上下文无关的,而HTML却相反,也正是它非上下文无关的特性,决定了HTML Parser并不能使用常规编程语言的解析器来完成,需要另辟蹊径。

解析算法

HTML5 规范详细地介绍了解析算法。这个算法分为两个阶段:

  1. 标记化。

  2. 建树。

对应的两个过程就是词法分析语法分析

标记化算法

这个算法输入为 HTML文本 ,输出为HTML标记,也成为标记生成器。其中运用有限自动状态机来完成。即在当当前状态下,接收一个或多个字符,就会更新到下一个状态。

<html>  <body>    Hello sanyuan  </body></html>

通过一个简单的例子来演示一下标记化的过程。

遇到<, 状态为标记打开

接收[a-z]的字符,会进入标记名称状态

这个状态一直保持,直到遇到>,表示标记名称记录完成,这时候变为数据状态

接下来遇到body标签做同样的处理。

这个时候htmlbody的标记都记录好了。

现在来到<body>中的>,进入数据状态,之后保持这样状态接收后面的字符hello sanyuan

接着接收 </body> 中的<,回到标记打开, 接收下一个/后,这时候会创建一个end tag的token。

随后进入标记名称状态, 遇到>回到数据状态

接着以同样的样式处理 </body>。

建树算法

之前提到过,DOM 树是一个以document为根节点的多叉树。因此解析器首先会创建一个document对象。标记生成器会把每个标记的信息发送给建树器建树器接收到相应的标记时,会创建对应的 DOM 对象。创建这个DOM对象后会做两件事情:

  1. DOM对象加入 DOM 树中。

  2. 将对应标记压入存放开放(与闭合标签意思对应)元素的栈中。

还是拿下面这个例子说:

<html>  <body>    Hello sanyuan  </body></html>

首先,状态为初始化状态

接收到标记生成器传来的html标签,这时候状态变为before html状态。同时创建一个HTMLHtmlElement的 DOM 元素, 将其加到document根对象上,并进行压栈操作。

接着状态自动变为before head, 此时从标记生成器那边传来body,表示并没有head, 这时候建树器会自动创建一个HTMLHeadElement并将其加入到DOM树中。

现在进入到in head状态, 然后直接跳到after head

现在标记生成器传来了body标记,创建HTMLBodyElement, 插入到DOM树中,同时压入开放标记栈。

接着状态变为in body,然后来接收后面一系列的字符: Hello sanyuan。接收到第一个字符的时候,会创建一个Text节点并把字符插入其中,然后把Text节点插入到 DOM 树中body元素的下面。随着不断接收后面的字符,这些字符会附在Text节点上。

现在,标记生成器传过来一个body的结束标记,进入到after body状态。

标记生成器最后传过来一个html的结束标记, 进入到after after body的状态,表示解析过程到此结束。

容错机制

讲到HTML5规范,就不得不说它强大的宽容策略, 容错能力非常强,虽然大家褒贬不一,不过我想作为一名资深的前端工程师,有必要知道HTML Parser在容错方面做了哪些事情。

接下来是 WebKit 中一些经典的容错示例,发现有其他的也欢迎来补充。

使用</br>而不是<br>

if (t->isCloseTag(brTag) && m_document->inCompatMode()) {  reportError(MalformedBRError);  t->beginTag = true;}

全部换为<br>的形式。

表格离散

<table>  <table>    <tr><td>inner table</td></tr>  </table>  <tr><td>outer table</td></tr></table>

WebKit会自动转换为:

<table>    <tr><td>outer table</td></tr></table><table>    <tr><td>inner table</td></tr></table>

表单元素嵌套

这时候直接忽略里面的form

样式计算

关于CSS样式,它的来源一般是三种:

  1. link标签引用

  2. style标签中的样式

  3. 元素的内嵌style属性

格式化样式表

首先,浏览器是无法直接识别 CSS 样式文本的,因此渲染引擎接收到 CSS 文本之后第一件事情就是将其转化为一个结构化的对象,即styleSheets。

这个格式化的过程过于复杂,而且对于不同的浏览器会有不同的优化策略,这里就不展开了。

在浏览器控制台能够通过document.styleSheets来查看这个最终的结构。当然,这个结构包含了以上三种CSS来源,为后面的样式操作提供了基础。

标准化样式属性

有一些 CSS 样式的数值并不容易被渲染引擎所理解,因此需要在计算样式之前将它们标准化,如em->px,red->#ff0000,bold->700等等。

计算每个节点的具体样式

样式已经被格式化标准化,接下来就可以计算每个节点的具体样式信息了。

其实计算的方式也并不复杂,主要就是两个规则: 继承层叠

每个子节点都会默认继承父节点的样式属性,如果父节点中没有找到,就会采用浏览器默认样式,也叫UserAgent样式。这就是继承规则,非常容易理解。

然后是层叠规则,CSS 最大的特点在于它的层叠性,也就是最终的样式取决于各个属性共同作用的效果,甚至有很多诡异的层叠现象,看过《CSS世界》的同学应该对此深有体会,具体的层叠规则属于深入 CSS 语言的范畴,这里就不过多介绍了。

不过值得注意的是,在计算完样式之后,所有的样式值会被挂在到window.computedStyle当中,也就是可以通过JS来获取计算后的样式,非常方便。

生成布局树

现在已经生成了DOM树DOM样式,接下来要做的就是通过浏览器的布局系统确定元素的位置,也就是要生成一棵布局树(Layout Tree)。

布局树生成的大致工作如下:

  1. 遍历生成的 DOM 树节点,并把他们添加到布局树中

  2. 计算布局树节点的坐标位置。

值得注意的是,这棵布局树值包含可见元素,对于 head标签和设置了display: none的元素,将不会被放入其中。

有人说首先会生成Render Tree,也就是渲染树,其实这还是 16 年之前的事情,现在 Chrome 团队已经做了大量的重构,已经没有生成Render Tree的过程了。而布局树的信息已经非常完善,完全拥有Render Tree的功能。

之所以不讲布局的细节,是因为它过于复杂,一一介绍会显得文章过于臃肿,不过大部分情况下我们只需要知道它所做的工作是什么即可,如果想深入其中的原理,知道它是如何来做的,我强烈推荐你去读一读人人FED团队的文章从Chrome源码看浏览器如何layout布局。

关于“输入URL后页面会发生什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

输入URL后页面会发生什么

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

输入URL后页面会发生什么

这篇文章主要介绍“输入URL后页面会发生什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“输入URL后页面会发生什么”文章能帮助大家解决问题。构建 DOM 树由于浏览器无法直接理解 HTML字符串
2023-06-27

面试必问:从输入url到页面展示到底发生了什么

刚开始写这篇文章还是挺纠结的,因为网上搜索“从输入url到页面展示到底发生了什么”,你可以搜到一大堆的资料。而且面试这道题基本是必考题,二月份面试的时候,虽然知道这个过程发生了什么,不过当面试官一步步追问下去的,很多细节就不太清楚了。本文的
2023-07-26

输入网址按回车会发生什么

这篇文章主要介绍“输入网址按回车会发生什么”,在日常操作中,相信很多人在输入网址按回车会发生什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”输入网址按回车会发生什么”的疑惑有所帮助!接下来,请跟着小编一起来
2023-06-16

在浏览器输入了baidu.com按下回车后会发生什么

本篇内容介绍了“在浏览器输入了baidu.com按下回车后会发生什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!你真的理解URL是什么?我
2023-06-02

从输入URL到页面显示过程原理是什么

这篇文章主要讲解了“从输入URL到页面显示过程原理是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“从输入URL到页面显示过程原理是什么”吧!前言说说从输入 URL 到页面显示的过程,这是
2023-07-06

vbs生成静态页面过程中会出现什么问题

这篇文章主要介绍了vbs生成静态页面过程中会出现什么问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。vbs是否能够实现如下的:访问某个aspx页面,然后把服务器返回的页面以
2023-06-08

这些结构的幕后发生了什么? struct 会被复制吗?

问题内容我不明白这段代码到底发生了什么。接收方 func 在原始结构 user 上工作(因为指针),因此在 func 内部我们更改了原始 obj。但是结构地址也是原始的还是原始“a”的副本?func main() {a := addr
这些结构的幕后发生了什么? struct 会被复制吗?
2024-02-06

当我在 AUTO_INCRMENT MySQL 列中插入值“NULL”时会发生什么?

当我们向 AUTO_INCRMENT 列插入 NULL 值时,MySQL 将返回序列号。示例mysql> Create table employee(id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, N
2023-10-22

当向 MySQL 中的 UNSIGNED 列插入负值时会发生什么?

在MySQL中,当您将负值设置给UNSIGNED列时,会出现错误。例如,让我们首先创建一个带有一个UNSIGNED字段的表 −mysql> create table UnsignedDemo-> (-> Id int UNSIGNED->
2023-10-22

如果 MySQL TIMEDIFF() 函数的输出超出 TIME 字段的范围值会发生什么

如果 MySQL TIMEDIFF() 函数的输出超出 TIME 字段的范围值,MySQL 会将超出范围的部分截断,只保留在 TIME 字段范围内的部分。例如,如果 TIMEDIFF() 函数的输出超过了 838:59:59(HH:MM:S
2023-10-20

第14问:在 MGR 集群里,一个节点异常退出后,会发生什么?

本文关键字:MGR、监控、Wireshark问题在一个 MGR 集群里,一个节点异常退出后,MySQL 会如何进行调度?异常的节点什么时候会被踢出集群?实验实验开始前,给大家分享一个小经验:选择合适的观测工具,如果没有,就创造一个。我们先使用三台虚拟机,创建一
第14问:在 MGR 集群里,一个节点异常退出后,会发生什么?
2018-06-21

如果 MySQL TIMEDIFF() 函数的输出超出 TIME 字段的范围值会发生什么?

我们知道MySQL中TIME字段的范围是‘-838:59:59’到‘838:59:59’。现在,如果 TIMEDIFF() 函数的输出超出此范围,则 MySQL 将返回 '-838:59:59' 或 '838:59:59',具体取决于参数的
2023-10-22

如果我跳过第五个参数的值(即多个位),MySQL EXPORT_SET() 函数的输出会发生什么情况?

实际上,第五个参数的默认值(即位数)是 64,因此如果我们不在第五个参数上指定任何值,MySQL 将检查最多 64 位的位并生成结果。可以从下面的例子来理解 -例子mysql> SELECT EXPORT_SET(5, Y,N, )\G*
2023-10-22

如果我跳过第四个和第五个参数,即分隔符和位数,MySQL EXPORT_SET() 函数的输出会发生什么?

我们知道第五个参数的默认值(即位数)是 64,因此如果我们不在第五个参数上指定任何值,MySQL 将检查最多 64 位的位并生成结果。然而,在跳过第四个参数(即分隔符)时,MySQL 将在显示输出时使用逗号 (,) 作为分隔符。示例mysq
2023-10-22

javascript当页面当前的被选择内容被复制后触发此事件使用什么函数,详细讲解

JavaScript中使用addEventListener()函数可以监听copy事件,当用户复制页面上选定的文本时触发。该事件提供clipboardData信息,并可用于跟踪复制文本、显示提示或执行其他基于文本的操作。可使用捕获或冒泡模型,并可随时移除监听器。并非所有浏览器全面支持copy事件,且某些元素可能无法触发。
javascript当页面当前的被选择内容被复制后触发此事件使用什么函数,详细讲解
2024-04-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录