vnsr威尼斯城官网登入首先判断你输入的是一个合法的 URL 还是一个待搜索的关键词

当前位置:vns6060威尼斯城官网 > vnsr威尼斯城官网登入 > vnsr威尼斯城官网登入首先判断你输入的是一个合法的 URL 还是一个待搜索的关键词
作者: vns6060威尼斯城官网|来源: http://www.oneblack.net|栏目:vnsr威尼斯城官网登入

文章关键词:vns6060威尼斯城官网,预解核

  这个问题已经是老生常谈了,更是经常被作为面试的压轴题出现,网上也有很多文章,但最近闲的无聊,然后就自己做了一篇笔记,感觉比之前理解更透彻了。

  这篇笔记是我这两天看了数十篇文章总结出来的,所以相对全面一点,但由于我是做前端的,所以会比较重点分析浏览器渲染页面那一部分,至于其他部分我会罗列出关键词,感兴趣的可以自行查阅,

  注意:本文的步骤是建立在,请求的是一个简单的 HTTP 请求,没有 HTTPS、HTTP2、最简单的 DNS、没有代理、并且服务器没有任何问题的基础上,尽管这是不切实际的。

  首先判断你输入的是一个合法的 URL 还是一个待搜索的关键词,并且根据你输入的内容进行自动完成、字符编码等操作。

  由于安全隐患,会使用 HSTS 强制客户端使用 HTTPS 访问页面。详见:你所不知道的 HSTS[1]。

  浏览器还会进行一些额外的操作,比如安全检查、访问限制(之前国产浏览器限制 996.icu)。

  操作系统也有自己的 DNS缓存,但在这之前,会向检查域名是否存在本地的 Hosts 文件里,没有则向 DNS 服务器发送查询请求。

  ISP DNS 就是在客户端电脑上设置的首选 DNS 服务器,它们在大多数情况下都会有缓存。

  在前面所有步骤没有缓存的情况下,本地 DNS 服务器会将请求转发到互联网上的根域,下面这个图很好的诠释了整个流程:

  递归方式:一路查下去中间不返回,得到最终结果才返回信息(浏览器到本地DNS服务器的过程)

  在前面的步骤我们已经得到服务器的 IP 地址,浏览器会开始构造一个 HTTP 报文,其中包括:

  请求报头(Request Header):请求方法、目标地址、遵循的协议等等

  浏览器只能发送 GET、POST 方法,而打开网页使用的是 GET 方法

  传输层会发起一条到达服务器的 TCP 连接,为了方便传输,会对数据进行分割(以报文段为单位),并标记编号,方便服务器接受时能够准确地还原报文信息。

  判断目标地址是否与当前地址处于同一网络中,是的话直接根据 Mac 地址发送,否则使用路由表查找下一跳地址,以及使用 ARP 协议查询它的 Mac 地址。

  注意:在 OSI 参考模型中 ARP 协议位于链路层,但在 TCP/IP 中,它位于网络层。

  以太网规定了连入网络的所有设备都必须具备“网卡”接口,数据包都是从一块网卡传递到另一块网卡,网卡的地址就是 Mac 地址。每一个 Mac 地址都是独一无二的,具备了一对一的能力。

  发送数据的方法很原始,直接把数据通过 ARP 协议,向本网络的所有机器发送,接收方根据标头信息与自身 Mac 地址比较,一致就接受,否则丢弃。

  接受 TCP 报文后,会对连接进行处理,对HTTP协议进行解析(请求方法、域名、路径等),并且进行一些验证:

  假如服务器配置了 HTTP 重定向,就会返回一个301永久重定向响应,浏览器就会根据响应,重新发送 HTTP 请求(重新执行上面的过程)。

  然后会查看 URL 重写规则,如果请求的文件是真实存在的,比如图片、html、css、js文件等,则会直接把这个文件返回。

  然后根据动态语言的脚本,来决定调用什么类型的动态文件解释器来处理这个请求。

  以 PHP 语言的 MVC 框架举例,它首先会初始化一些环境的参数,根据 URL 由上到下地去匹配路由,然后让路由所定义的方法去处理请求。

  首先查看 Response header,根据不同状态码做不同的事(比如上面提到的重定向)。

  接下来,根据响应资源里的MIME[3]类型去解析响应内容(比如 HTML、Image各有不同的解析方式)。

  传输回来的其实都是一些二进制字节数据,浏览器需要根据文件指定编码(例如UTF-8)转换成字符串,也就是HTML 代码。

  预解析做的事情是提前加载资源,减少处理时间,它会识别一些会请求资源的属性,比如img标签的src属性,并将这个请求加到请求队列中。

  符号化是词法分析的过程,将输入解析成符号,HTML 符号包括,开始标签、结束标签、属性名和属性值。

  它通过一个状态机去识别符号的状态,比如遇到,状态都会产生变化。

  注意:符号化和构建树是并行操作的,也就是说只要解析到一个开始标签,就会创建一个 DOM 节点。

  在上一步符号化中,解析器获得这些标记,然后以合适的方法创建DOM对象并把这些符号插入到DOM对象中。

  你从来没有在浏览器看过类似”语法无效”的错误,这是因为浏览器去纠正错误的语法,然后继续工作。

  当整个解析的过程完成以后,浏览器会通过DOMContentLoaded事件来通知DOM解析完成。

  一旦浏览器下载了 CSS,CSS 解析器就会处理它遇到的任何 CSS,根据语法规范[4]解析出所有的 CSS 并进行标记化,然后我们得到一个规则表。

  在匹配一个节点对应的 CSS 规则时,是按照从右到左的顺序的,例如:div p { font-size :14px }会先寻找所有的p标签然后判断它的父元素是否为div。

  所以我们写 CSS 时,尽量用 id 和 class,千万不要过度层叠。

  注意:渲染树会忽略那些不需要渲染的节点,比如设置了display:none的节点。

  通过计算让任何尺寸值都减少到三个可能之一:auto、百分比、px,比如把rem转化为px。

  浏览器需要一种方法来确定哪些样式才真正需要应用到对应元素,所以它使用一个叫做specificity的公式,这个公式会通过:

  当遇到一个script标签时,DOM 构建会被暂停,直至脚本完成执行,然后继续构建 DOM 树。

  但如果 JS 依赖 CSS 样式,而它还没有被下载和构建时,vnsr威尼斯城官网登入浏览器就会延迟脚本执行,直至 CSS Rules 被构建。

  另外,如果要改变阻塞模式,可以使用 defer 与 async,详见:这篇文章[5]

  确定渲染树种所有节点的几何属性,比如:位置、大小等等,最后输入一个盒子模型,它能精准地捕获到每个元素在屏幕内的准确位置与大小。

  当浏览器发现某个部分发现变化影响了布局时,需要倒回去重新渲染,会从html标签开始递归往下,重新计算位置和大小。

  reflow基本是无法避免的,因为当你滑动一下鼠标、resize 窗口,页面就会产生变化。

  改变了某个元素的背景色、文字颜色等等不会影响周围元素的位置变化时,就会发生重绘。

  JS 脚本加载完毕后,会首先进入语法分析阶段,它首先会分析代码块的语法是否正确,不正确则抛出“语法错误”,停止执行。

  分词,例如将var a = 2,,分成var、a、=、2这样的词法单元。

  每进入一个不同的运行环境都会创建一个对应的执行上下文,根据不同的上下文环境,形成一个函数调用栈,栈底永远是全局执行上下文,栈顶则永远是当前执行上下文。

  JS 引擎线程:也叫 JS 内核,负责解析执行 JS 脚本程序的主线 引擎

  事件触发线程:属于浏览器内核线程,主要用于控制事件,例如鼠标、键盘等,当事件被触发时,就会把事件的处理函数推进事件队列,等待 JS 引擎线程执行

  定时器触发线程:主要控制setInterval和setTimeout,用来计时,计时完毕后,则把定时器的处理函数推进事件队列中,等待 JS 引擎线程。

  HTTP 异步请求线程:通过XMLHttpRequest连接后,通过浏览器新开的一个线程,监控readyState状态变更时,如果设置了该状态的回调函数,则将该状态的处理函数推进事件队列中,等待JS引擎线程执行。

  异步任务:不直接执行,只有满足触发条件时,相关的线程将该异步任务推进任务队列中,等待JS引擎主线程上的任务执行完毕时才开始执行,例如异步Ajax、DOM事件,setTimeout等。

网友评论

我的2016年度评论盘点
还没有评论,快来抢沙发吧!