通过与 Jira 对比,让您更全面了解 PingCode

  • 首页
  • 需求与产品管理
  • 项目管理
  • 测试与缺陷管理
  • 知识管理
  • 效能度量
        • 更多产品

          客户为中心的产品管理工具

          专业的软件研发项目管理工具

          简单易用的团队知识库管理

          可量化的研发效能度量工具

          测试用例维护与计划执行

          以团队为中心的协作沟通

          研发工作流自动化工具

          账号认证与安全管理工具

          Why PingCode
          为什么选择 PingCode ?

          6000+企业信赖之选,为研发团队降本增效

        • 行业解决方案
          先进制造(即将上线)
        • 解决方案1
        • 解决方案2
  • Jira替代方案

25人以下免费

目录

浏览器输入url按下回车后发生了什么

浏览器输入url按下回车后发生了:一、URL 解析;二、DNS 查询;三、TCP 连接;四、处理请求;五、接受响应;六、渲染页面。URL 解析是指将用户在浏览器地址栏输入的URL字符串解析成浏览器可以理解并处理的格式。

一、URL 解析

1、地址解析

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

2、HSTS

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

3、其他操作

浏览器还会进行一些额外的操作,比如安全检查、访问限制。

4、检查缓存

URL解析完成后,浏览器会检查缓存,即判断本地是否已经缓存了请求的资源。如果缓存中已经有该资源并且缓存未过期,浏览器将从缓存中获取资源,否则就需要向服务器发送请求以获取最新的资源。

二、DNS 查询

1、浏览器缓存

浏览器会先检查是否在缓存中,没有则调用系统库函数进行查询。

2、操作系统缓存

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

3、路由器缓存

路由器也有自己的缓存。

4、ISP DNS 缓存

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

5、根域名服务器查询

在前面所有步骤没有缓存的情况下,本地 DNS 服务器会将请求转发到互联网上的根域。

三、TCP 连接

TCP/IP 分为四层,在发送数据时,每层都要对数据进行封装:

1、应用层:发送 HTTP 请求

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

  • 请求报头(Request Header):请求方法、目标地址、遵循的协议等等
  • 请求主体(其他参数)

其中需要注意的点:浏览器只能发送 GET、POST 方法,而打开网页使用的是 GET 方法。

2、传输层:TCP 传输报文

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

3、网络层:IP协议查询Mac地址

将数据段打包,并加入源及目标的IP地址,并且负责寻找传输路线。判断目标地址是否与当前地址处于同一网络中,是的话直接根据 Mac 地址发送,否则使用路由表查找下一跳地址,以及使用 ARP 协议查询它的 Mac 地址。

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

4、链路层:以太网协议

  • 以太网协议:根据以太网协议将数据分为以“帧”为单位的数据包,每一帧分为两个部分:标头:数据包的发送者、接受者、数据类型;数据:数据包具体内容。
  • Mac 地址:以太网规定了连入网络的所有设备都必须具备“网卡”接口,数据包都是从一块网卡传递到另一块网卡,网卡的地址就是 Mac 地址。每一个 Mac 地址都是独一无二的,具备了一对一的能力。
  • 广播:发送数据的方法很原始,直接把数据通过 ARP 协议,向本网络的所有机器发送,接收方根据标头信息与自身 Mac 地址比较,一致就接受,否则丢弃。

四、处理请求

1、HTTPD

最常见的 HTTPD 有 Linux 上常用的 Apache 和 Nginx,以及 Windows 上的 IIS。它会监听得到的请求,然后开启一个子进程去处理这个请求。

2、处理请求

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

  • 验证是否配置虚拟主机
  • 验证虚拟主机是否接受此方法
  • 验证该用户可以使用该方法(根据 IP 地址、身份信息等)

3、重定向

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

4、URL 重写

然后会查看 URL 重写规则,如果请求的文件是真实存在的,比如图片、html、css、js文件等,则会直接把这个文件返回。否则服务器会按照规则把请求重写到 一个 REST 风格的 URL 上。然后根据动态语言的脚本,来决定调用什么类型的动态文件解释器来处理这个请求。以 PHP 语言的 MVC 框架举例,它首先会初始化一些环境的参数,根据 URL 由上到下地去匹配路由,然后让路由所定义的方法去处理请求。

五、接受响应

浏览器接收到来自服务器的响应资源后,会对资源进行分析。首先查看 Response header,根据不同状态码做不同的事(比如上面提到的重定向)。如果响应资源进行了压缩(比如 gzip),还需要进行解压。然后,对响应资源做缓存。接下来,根据响应资源里的 MIME 类型去解析响应内容(比如 HTML、Image各有不同的解析方式)。

六、渲染页面

1、HTML 解析

首先要知道浏览器解析是从上往下一行一行地解析的。解析的过程可以分为四个步骤:

  • 解码(encoding):传输回来的其实都是一些二进制字节数据,浏览器需要根据文件指定编码(例如UTF-8)转换成字符串,也就是HTML代码。
  • 预解析(pre-parsing):预解析做的事情是提前加载资源,减少处理时间,它会识别一些会请求资源的属性,比如img标签的src属性,并将这个请求加到请求队列中。
  • 符号化(Tokenization):符号化是词法分析的过程,将输入解析成符号,HTML 符号包括,开始标签、结束标签、属性名和属性值。它通过一个状态机去识别符号的状态,比如遇到<,>状态都会产生变化。
  • 构建树(tree construction):在上一步符号化中,解析器获得这些标记,然后以合适的方法创建DOM对象并把这些符号插入到DOM对象中。

2、CSS 解析

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

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

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

3、渲染树

这是一个 DOM 树和 CSS 规则树合并的过程。

  • 计算:通过计算让任何尺寸值都减少到三个可能之一:auto、百分比、px,比如把rem转化为px。
  • 级联:浏览器需要一种方法来确定哪些样式才真正需要应用到对应元素,所以它使用一个叫做specificity的公式,这个公式会通过:标签名、class、id,是否内联样式,!important,然后得出一个权重值,取较高的那个。
  • 渲染阻塞:当遇到一个script标签时,DOM 构建会被暂停,直至脚本完成执行,然后继续构建 DOM 树。但如果 JS 依赖 CSS 样式,而它还没有被下载和构建时,浏览器就会延迟脚本执行,直至 CSS Rules 被构建。

4、布局与绘制

确定渲染树种所有节点的几何属性,比如:位置、大小等等,最后输入一个盒子模型,它能精准地捕获到每个元素在屏幕内的准确位置与大小。然后遍历渲染树,调用渲染器的 paint() 方法在屏幕上显示其内容。

5、合并渲染层

把以上绘制的所有图片合并,最终输出一张图片。

6、回流与重绘

  • 回流(reflow):当浏览器发现某个部分发现变化影响了布局时,需要倒回去重新渲染,会从html标签开始递归往下,重新计算位置和大小。reflow基本是无法避免的,因为当你滑动一下鼠标、resize 窗口,页面就会产生变化。
  • 重绘(repaint):改变了某个元素的背景色、文字颜色等等不会影响周围元素的位置变化时,就会发生重绘。每次重绘后,浏览器还需要合并渲染层并输出到屏幕上。回流的成本要比重绘高很多,所以我们应该尽量避免产生回流。

7、JavaScript 编译执行

可以分为三个阶段:

  • 词法分析:JS 脚本加载完毕后,会首先进入语法分析阶段,它首先会分析代码块的语法是否正确,不正确则抛出“语法错误”,停止执行。
  • 预编译:JS 有三种运行环境:全局环境、函数环境、eval。每进入一个不同的运行环境都会创建一个对应的执行上下文,根据不同的上下文环境,形成一个函数调用栈,栈底永远是全局执行上下文,栈顶则永远是当前执行上下文。
  • 执行:JS 引擎会按照代码的顺序逐行执行,遇到函数调用时,将会创建一个新的执行上下文,并将其推入栈顶,直到执行完毕返回结果并将该上下文弹出栈。

延伸阅读1:什么是URL

URL 代表着是统一资源定位符(Uniform Resource Locator)。URL 无非就是一个给定的独特资源在 Web 上的地址。理论上说,每个有效的 URL 都指向一个少数的资源。这个资源可以是一个 HTML 页面,一个 CSS 文档,一幅图像,等等。而在实际中,也有一些例外,最常见的情况就是一个 URL 指向了不存在的或是被移动过的资源。由于通过 URL 呈现的资源和 URL 本身由 Web 服务器处理,因此 web 服务器的拥有者需要认真地维护资源以及与它关联的 URL。

相关文章