从输入 URL 到页面展示发生了什么?

从输入 URL 到页面展示完整流程示意图

浏览器进程主要负责用户交互、子进程管理和文件储存等功能。
网络进程是面向渲染进程和浏览器进程等提供网络下载功能。
渲染进程的主要职责是把从网络下载的 HTML、JavaScript、CSS、图片等资源解析为可以显示和交互的页面。运行在渲染进程里面的代码是不被信任的。

  1. 输入地址
    用户输入查询关键字后,地址栏会判断输入的关键字是搜索内容还是请求的 URL。

    • 如果是搜索内容,地址栏会使用浏览器默认的搜索引擎,来合成带关键字的 URL。
    • 如果输入内容符合 URL 规则,地址栏会根据规则,把内容加上协议,合成完整的 URL。

    浏览器进程处理完 URL 后,会发出 URL 请求给网络进程。

  1. 查找浏览器缓存,如果有缓存,直接返回资源。否则,进入网络请求流程。请求前的第一步要进行 DNS 解析,以获取请求域名的服务器 IP 地址。如果请求协议是 HTTPS,那么
    还需要建立 TLS 连接。
  1. 域名解析(即 DNS 解析),即浏览器查找域名的 IP 地址

    • 请求一旦发起,浏览器首先要做的事情就是解析这个域名,一般来说,浏览器会首先查看本地硬盘的 hosts 文件,看看其中有没有和这个域名对应的规则,如果有的话就直接使用 hosts 文件里面的 ip 地址。

    • 如果在本地的 hosts 文件没有能够找到对应的 ip 地址,浏览器会发出一个 DNS 请求到本地 DNS 服务器 。本地 DNS 服务器一般都是你的网络接入服务器商提供,比如中国电信,中国移动。

    • 查询你输入的网址的 DNS 请求到达本地 DNS 服务器之后,本地 DNS 服务器会首先查询它的缓存记录,如果缓存中有此条记录,就可以直接返回结果,此过程是递归的方式进行查询。如果没有,本地 DNS 服务器还要向 DNS 根服务器进行查询。

    • 根 DNS 服务器没有记录具体的域名和 IP 地址的对应关系,而是告诉本地 DNS 服务器,你可以到域服务器上去继续查询,并给出域服务器的地址。(叫做迭代)

    • 本地 DNS 服务器继续向域服务器发出请求,在这个例子中,请求的对象是 .com 域服务器。.com 域服务器收到请求之后,也不会直接返回域名和 IP 地址的对应关系,而是告诉本地 DNS 服务器,你的域名的解析服务器的地址。

    • 最后,本地 DNS 服务器向域名的解析服务器发出请求,这时就能收到一个域名和 IP 地址对应关系,本地 DNS 服务器不仅要把 IP 地址返回给用户电脑,还要把这个对应关系保存在缓存中,以备下次别的用户查询时,可以直接返回结果,加快网络访问。

    扩展:

    1. 什么是 DNS ?
      DNS(Domain Name System,域名系统),因特网上作为域名和 IP 地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的 IP 数串。通过主机名,最终得到该主机名对应的 IP 地址的过程叫做域名解析(或主机名解析)。
      通俗的讲,DNS 就相当于一个电话本,比如你要找 www.baidu.com 这个域名,那翻一翻电话本,就知道,哦,它的电话(ip)是 167.23.10.2。

    2. DNS 查询的两种方式:递归查询和迭代查询
      当局部 DNS 服务器自己不能回答客户机的 DNS 查询时,它就需要向其他DNS服务器进行查询。此时有两种方式,递归查询和迭代查询。

      • 递归查询:局部 DNS 服务器自己负责向其他 DNS 服务器进行查询,一般是先向该域名的根域服务器查询,再由根域名服务器一级级向下查询。最后得到的查询结果返回给局部 DNS 服务器,再由局部 DNS 服务器返回给客户端。


        递归查询
      • 迭代查询:局部 DNS 服务器不是自己向其他 DNS 服务器进行查询,而是把能解析该域名的其他 DNS 服务器的 IP 地址返回给客户端 DNS 程序,客户端 DNS 程序再继续向这些 DNS 服务器进行查询,直到得到查询结果为止。也就是说,迭代解析只是帮你找到相关的服务器而已,而不会帮你去查。


        迭代查询
    3. DNS 域名称空间的组织方式

      名称类型 说明 示例
      根域 DNS 域名中使用时,规定由尾部句点(.)来指定名称位于根或更高级别的域层次结构 单个句点 (.) 或句点用于末尾的名称
      顶级域 用来指示某个国家 / 地区或组织使用的名称的类型名称 .com
      第二层域 个人或组织在 Internet 上使用的注册名称 qq.com
      子域 已注册的二级域名派生的域名,通俗的讲就是网站名 www.qq.com
      主机或资源名称 通常情况下,DNS 域名的最左侧的标签标识网络上的特定计算机 h1.www.qq.com(h1 是主机名称)
    4. DNS 负载均衡
      当一个网站有足够多的用户的时候,假如每次请求的资源都位于同一台机器上面,那么这台机器随时可能会崩掉。处理办法就是用 DNS 负载均衡技术,它的原理是在 DNS 服务器中为同一个主机名配置多个 IP 地址,在应答 DNS 查询时,DNS 服务器对每个查询将以 DNS 文件中主机记录的 IP 地址按顺序返回不同的解析结果,将客户端的访问引导到不同的机器上去,使得不同的客户端访问不同的服务器,从而达到负载均衡的目的。

  2. 建立TCP连接,即三次握手
    获取到服务器的 IP 地址后,浏览器会向对应的 web 服务器(Nginx,Apache...)发起 TCP / IP 连接请求,通过三次握手,建立TCP连接。

    扩展:

    1. TCP 三次握手(为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误,防止 server 端一直等待,浪费资源)

      TCP 三次握手

      第一次握手:客户端向服务器发送 SYN(Synchronize Sequence Numbers 同步序列编号)标志位(序号是J),并且进入 SYN_SEND 状态(等待服务器确认状态)。

      第二次握手:服务器收到客户端的 SYN J 后,服务端会确认该数据包已收到并发送 ACK 标志位(序号是J+1)和 SYN 标志位(序号是K),服务器进入 SYN_RECV 状态(请求接收并等待客户端确认状态)。

      第三次握手:客户端进入连接建立状态,向服务端发送 ACK 标志位(序号是K+1),确认客户端已收到建立连接确认,服务端收到 ACK 位后,服务端进入ESTABLISHED 状态(连接已建立状态)。 第三次握手的时候,是可以携带数据的。但是,第一次、第二次握手不可以携带数据。

  1. 建立 Http 请求
    建立了 TCP 连接之后,浏览器向 web 服务器发起一个 http 请求。
    一个典型的 http request header 一般需要包括请求的方法,例如 GET 或者 POST 等,不常用的还有 PUT 和 DELETE 、HEAD、OPTION 以及 TRACE 方法,一般的浏览器只能发起 GET 或者 POST 请求。请求信息包含三个部分:请求方法 URL 协议 / 版本、请求头(Request Header)、请求正文。

    扩展:

    1. 301 和 302 的区别。
      共同点:都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的 URL 地址,这个地址可以从响应的 Location 首部中获取(用户看到的效果就是他输入的地址 A 瞬间变成了另一个地址 B)。
      不同点:301 表示旧地址 A 的资源已经被永久地移除了(不可访问),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;302 表示旧地址 A 的资源还在(仍然可以访问),这个重定向只是临时地从旧地址 A 跳转到地址 B,搜索引擎会抓取新的内容而保存旧的网址。SEO 302 好于 301。

    2. 重定向原因:

      • 网站调整(如改变网页目录结构);
      • 网页被移到一个新地址;
      • 网页扩展名改变(如应用需要把 .php 改成 .Html 或 .shtml);
      • 某些注册了多个域名的网站,需要通过重定向让访问这些域名的用户自动跳转到主站点等。
  1. 服务器处理 Http 请求
    服务器在接收到请求后,解析用户请求,知道了要调度哪些资源文件,再通过相应的资源文件,处理用户的请求和参数,并调用数据库信息,最后将结果通过 web 服务器返回给浏览器。
    代理服务器处理 HTTP 通信过程中的中间位置,对上屏蔽了真实客户端,对下屏蔽了真实服务器。代理的一个常见的功能就是负载均衡,可以掌握请求分发的“大权”,决定由后面的哪台服务器响应请求。目的就是尽量把外部流量合理地分散到多台源服务器,提高系统的整体资源利用率和性能。
  1. 关闭 TCP 连接,即四次挥手
    在这次数据传输完成后,为了避免服务器与客户端双方的资源占用和损耗,会经过四次挥手,关闭TCP连接。

    四次挥手

    响应数据类型处理:Content-Type 是 HTTP 头中一个非常重要的字段, 它告诉浏览器服务器返回的响应体数据是什么类型,然后浏览器会根据 Content-Type 的值来决定如
    何显示响应体的内容。application/octet-stream,显示数据是字节流类型的,被浏览器判断为下载类型,那么该请求会被提交给浏览器的下载管理器,同时该 URL 请求的导航流程就此结束。但如果是HTML,那么浏览器则会继续进行导航流程。接下来就需要准备渲染进程了。

扩展:
1. TCP四次挥手
    第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于 FIN_WAIT1 状态。
    即发出连接释放报文段(FIN=1,序号seq=u),并停止再发送数据,主动关闭TCP连接,进入FIN_WAIT1(终止等待1)状态,等待服务端的确认。

    第二次挥手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。
    即服务端收到连接释放报文段后即发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v),服务端进入CLOSE_WAIT(关闭等待)状态,此时的TCP处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入FIN_WAIT2(终止等待2)状态,等待服务端发出的连接释放报文段。

    第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。
    即服务端没有要向客户端发出的数据,服务端发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),服务端进入LAST_ACK(最后确认)状态,等待客户端的确认。

    第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态,服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。
    即客户端收到服务端的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),客户端进入 TIME_WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入 CLOSED 状态。

    收到一个 FIN 只意味着在这一方向上没有数据流动。客户端执行主动关闭并进入 TIME_WAIT 是正常的,服务端通常执行被动关闭,不会进入 TIME_WAIT 状态。

2. 为什么建立连接是三次握手,而关闭连接却是四次挥手呢?
    中断连接端可以是Client端,也可以是Server端。
    服务端在 LISTEN 状态下,收到建立连接请求的 SYN 报文后,把 ACK 和 SYN 放在一个报文里发送给客户端。而关闭连接时,当收到对方的 FIN 报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送 FIN 报文给对方来表示同意现在关闭连接,因此,己方 ACK 和 FIN 一般都会分开发送。
  1. 浏览器解析资源
    在拿到 html、css、js、图片等资源后,浏览器开始解析。

    • 渲染进程将 HTML 内容转换为 DOM 树结构;
    • 渲染引擎将 CSS 样式表转化为 styleSheets,计算出 DOM 节点的样式;
    • 生成渲染树。

    Chrome 的默认策略是,每个标签对应一个渲染进程。但如果从一个页面打开了另一个新
    页面,而新页面和当前页面属于同一站点(协议 + 根域名相同)的话,那么新页面会复用父页面的渲染进程。官方把这个默认策略叫 process-per-site-instance。

  1. 浏览器渲染页面
    生成渲染树后,浏览器根据渲染树布局页面,同时计算 css 样式或 js 对 Dom 的动态样式改变,然后绘制出页面。

你可能感兴趣的:(从输入 URL 到页面展示发生了什么?)