10-从输入址到获得页面的过程

开发岗中总是会考很多计算机网络的知识点,但如果让面试官只靠一道题,便涵盖最多的计网知识点,那可能就是 网页浏览的全过程 了。

总的来说,网络通信模型可以用下图来表示,也就是大家只要熟记网络结构五层模型,按照这个体系,很多知识点都能顺出来了。访问网页的过程也是如此。

开始之前,我们先简单过一遍完整流程:

  1. 在浏览器中输入指定网页的 URL。
  2. 浏览器通过 DNS 协议,获取域名对应的 IP 地址。
  3. 浏览器根据 IP 地址和端口号,向目标服务器发起一个 TCP 连接请求。
  4. 浏览器在 TCP 连接上,向服务器发送一个 HTTP 请求报文,请求获取网页的内容。
  5. 服务器收到 HTTP 请求报文后,处理请求,并返回 HTTP 响应报文给浏览器。
  6. 浏览器收到 HTTP 响应报文后,解析响应体中的 HTML 代码,渲染网页的结构和样式,同时根据 HTML 中的其他资源的 URL(如图片、CSS、JS 等),再次发起 HTTP 请求,获取这些资源的内容,直到网页完全加载显示。
  7. 浏览器在不需要和服务器通信时,可以主动关闭 TCP 连接,或者等待服务器的关闭请求。

详细一点的流程

  1. 浏览器查询 DNS,获取域名对应的 IP 地址。具体过程包括 浏览器搜索自身的 DNS 缓存 --> 搜索操作系统的 DNS 缓存 --> 读取本地的 hosts 文件 --> 向本地 DNS 服务器进行查询 等。

    1. 浏览器首先搜索浏览器的 DNS 缓存,浏览器 DNS 缓存中维护着一张 域名 与 IP 地址的对应表,有就先调用这个IP完成解析。
    2. 如果没有,则继续搜索 操作系统的 DNS 缓存,如果有直接返回 IP 完成解析。这两个缓存,可以理解为本地解析器缓存。
      • 一般来说,当电脑第一次成功访问某一网站后,在一定时间内,浏览器或操作系统会缓存他的 IP 地址(DNS解析记录).
    3. 如果操作系统的 DNS 缓存也没有目标域名的解析记录,系统会检查本地主机文件(hosts文件),如果有,则完成解析并返回。
    4. 如果本地主机文件也没有该域名的解析信息,浏览器会向配置的默认 DNS 服务器发出查询请求。
      • 对于向本地 DNS 服务器进行查询,如果要查询的域名包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析(此解析具有权威性);
      • 如果要查询的域名不由本地 DNS 服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个 IP 地址映射,完成域名解析(此解析不具有权威性)。
      • 如果本地域名服务器并未缓存该网址映射关系,那么将根据其设置发起递归查询或者迭代查询;
        • 递归查询:在该模式下 DNS 服务器接收到客户机请求,必须使用一个准确的查询结果回复客户机。如果 DNS 服务器本地没有存储查询 DNS 信息,那么该服务器会询问其他服务器,并将返回的查询结果提交给客户机。
          客户机和服务器之间的查询是递归查询。递归查询告诉客户机 IP。
        • 迭代查询:DNS 服务器会向客户机提供其他能够解析查询请求的 DNS 服务器地址,当客户机发送查询请求时,DNS 服务器并不直接回复查询结果,而是告诉客户机另一台 DNS 服务器地址,客户机再向这台 DNS 服务器提交请求,依次循环直到返回查询的结果为止。
          服务器之间的查询是迭代查询。


    本地域名服务器将得到的 IP 地址返回给操作系统,同时自己将 IP 地址缓存起来
    操作系统将 IP 地址返回给浏览器,同时自己也将 IP 地址缓存起
    浏览器就得到了域名对应的 IP 地址,并将 IP 地址缓存起

  2. 浏览器获得域名对应的 IP 地址以后,浏览器向服务器请求建立链接,发起三次握手。
    应用层会下发数据给传输层,这里 TCP 协议会指明两端的端口号,然后下发给网络层。网络层中的 IP 协议会确定 IP 地址,并且指示了数据传输中如何跳转路由器。
    然后包会再被封装到数据链路层的数据帧结构中,最后就是物理层面的传输了。

  3. TCP 握手结束后,如果使用 HTTPS 协议会进行 TLS 握手,然后就开始正式的传输数据。浏览器向服务器发送 HTTP 请求。例如:GET /sample/hello.jsp HTTP/1.1

  4. 数据在进入服务端之前,可能还会先经过负责负载均衡的服务器,它的作用就是将请求合理的分发到多台服务器上。
    然后服务器接收到这个请求,并根据路径参数映射到特定的请求处理器进行处理,并将处理结果及相应的视图返回给浏览器。这时假设服务端会响应一个 HTML 文件。

  5. 浏览器拿到响应数据之后,会判断状态码是什么:

    • 如果是 200 那就继续解析
    • 如果是 400 或 500 的话就会报错
    • 如果是 300 的话会进行重定向,这里会有个重定向计数器,避免过多次的重定向,超过次数也会报错
  6. 浏览器根据其请求到的资源、数据渲染页面,最终向用户呈现一个完整的页面。

    • 如果是 gzip 格式的话会先解压一下,然后通过文件的编码格式知道该如何去解码文件。
    • 文件解码成功后会正式开始渲染流程
      • 先会根据 HTML 构建 DOM 树,有 CSS 的话会去构建 CSSOM 树。
      • 如果遇到 script 标签的话,会判断是否存在 async 或者 defer,前者会并行进行下载并执行 JS,后者会先下载文件,然后等待 HTML 解析完成后顺序执行,如果以上都没有,就会阻塞住渲染流程直到 JS 执行完毕。
      • 遇到文件下载的会去下载文件,这里如果使用 HTTP 2.0 协议的话会极大的提高多图的下载效率。
    • 初始的 HTML 被完全加载和解析后会触发 DOMContentLoaded 事件。
    • CSSOM 树和 DOM 树构建完成后会开始生成 Render 树,这一步就是确定页面元素的布局、样式等等诸多方面的东西。
    • 在生成 Render 树的过程中,浏览器就开始调用 GPU 绘制,合成图层,将内容显示在屏幕上了。
  7. Web 服务器关闭 TCP 连接。

应用层

一切的开始——打开浏览器,在地址栏输入 URL,回车确认。那么,什么是 URL?访问 URL 有什么用?

URL

URL(Uniform Resource Locators),即统一资源定位器。网络上的所有资源都靠 URL 来定位,每一个文件就对应着一个 URL,就像是路径地址。理论上,文件资源和 URL 一一对应。实际上也有例外,比如某些 URL 指向的文件已经被重定位到另一个位置,这样就有多个 URL 指向同一个文件。

URL 的组成结构

URL的组成结构

  1. 协议。URL 的前缀通常表示了该网址采用了何种应用层协议,通常有两种——HTTP 和 HTTPS。当然也有一些不太常见的前缀头,比如文件传输时用到的ftp:
  2. 域名。域名便是访问网址的通用名,这里也有可能是网址的 IP 地址,域名可以理解为 IP 地址的可读版本,毕竟绝大部分人都不会选择记住一个网址的 IP 地址。
  3. 端口。如果指明了访问网址的端口的话,端口会紧跟在域名后面,并用一个冒号隔开。
  4. 资源路径。域名(端口)后紧跟的就是资源路径,从第一个/ 开始,表示从服务器上根目录开始进行索引到的文件路径,上图中要访问的文件就是服务器根目录下 /path/to/myfile.html。早先的设计是该文件通常物理存储于服务器主机上,但现在随着网络技术的进步,该文件不一定会物理存储在服务器主机上,有可能存放在云上,而文件路径也有可能是虚拟的(遵循某种规则)。
  5. 参数。参数是浏览器在向服务器提交请求时,在 URL 中附带的参数。服务器解析请求时,会提取这些参数。参数采用键值对的形式 key=value,每一个键值对使用 & 隔开。参数的具体含义和请求操作的具体方法有关。
  6. 锚点。锚点顾名思义,是在要访问的页面上的一个锚。要访问的页面大部分都多于一页,如果指定了锚点,那么在客户端显示该网页是就会定位到锚点处,相当于一个小书签。值得一提的是,在 URL 中,锚点以 # 开头,并且不会作为请求的一部分发送给服务端。

DNS

键入了 URL 之后,第一个重头戏登场——DNS 服务器解析。DNS(Domain Name System)域名系统,要解决的是 域名和 IP 地址的映射问题 。毕竟,域名只是一个网址便于记住的名字,而网址真正存在的地址其实是 IP 地址。

HTTP/HTTPS

利用 DNS 拿到了目标主机的 IP 地址之后,浏览器便可以向目标 IP 地址发送 HTTP 报文,请求需要的资源了。在这里,根据目标网站的不同,请求报文可能是 HTTP 协议或安全性增强的 HTTPS 协议。

传输层

由于 HTTP 协议是基于 TCP 协议的,在应用层的数据封装好以后,要交给传输层,经 TCP 协议继续封装。

TCP 协议保证了数据传输的可靠性,是数据包传输的主力协议。

网络层

终于,来到网络层,此时我们的主机不再是和另一台主机进行交互了,而是在和中间系统进行交互。也就是说,应用层和传输层都是端到端的协议,而网络层及以下都是中间件的协议了。

网络层的的核心功能——转发与路由,必会!!!如果面试官问到了网络层,而你恰好又什么都不会的话,最最起码要说出这五个字——转发与路由

  • 转发:将分组从路由器的输入端口转移到合适的输出端口。
  • 路由:确定分组从源到目的经过的路径。

所以到目前为止,我们的数据包经过了应用层、传输层的封装,来到了网络层,终于开始准备在物理层面传输了,第一个要解决的问题就是—— 往哪里传输?或者说,要把数据包发到哪个路由器上? 这便是 BGP 协议要解决的问题。


10-从输入址到获得页面的过程
https://flepeng.github.io/interview-10-网络-10-从输入址到获得页面的过程/
作者
Lepeng
发布于
2020年8月8日
许可协议