从URL输入到页面展现到底发生什么?

by LauCyun Sep 23,2014 11:10:01 2,386 views

0x0 前言

打开浏览器从输入网址到网页呈现在大家面前,背后到底发生了什么?经历怎么样的一个过程?先给大家来张总体流程图,具体步骤请看下文分解!


图1 流程图

总体来说分为以下几个过程:

  • DNS解析:将域名解析成IP地址
  • TCP连接:TCP三次握手
  • 发送HTTP请求
  • 服务器处理请求并返回HTTP报文
  • 浏览器解析渲染页面
  • 断开连接:TCP四次挥手

0x1 URL到底是啥

URL(Uniform Resource Locator),统一资源定位符,用于定位互联网上资源,俗称网址,比如:http://www.baidu.com/img/bd_logo1.png。

遵守语法规则是scheme://host.domain:port/path/filename,名词解释如下:

  • scheme:定义因特网服务的类型。常见的协议有HTTP、HTTPS、FTP、FILE,其中最常见的类型是HTTP,而HTTPS则是进行加密的网络传输;
  • host:定义域主机,HTTP的默认主机是www
  • domain:定义因特网域名,比如:www.baidu.com;
  • port:定义主机上的端口号,HTTP的默认端口号是80
  • path:定义服务器上的路径;
  • filename:定义文档/资源的名称。

0x2 域名解析(DNS)

在浏览器输入网址后,首先要经过域名解析,因为浏览器并不能直接通过域名找到对应的服务器,而是要通 IP地址。

大家这里或许会有个疑问:计算机既可以被赋予IP地址,也可以被赋予主机名和域名,比如www.baidu.com。那怎么不一开始就赋予个IP地址?这样就可以省去解析麻烦。我们先来了解下什么是IP地址

1 IP地址

IP地址是指互联网协议地址,是IPAddress的缩写。

IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。IP地址是一个32位的二进制数,比如127.0.0.1为本机 IP。

域名就相当于IP地址乔装打扮的伪装者,带着一副面具,它的作用就是便于记忆和沟通的一组服务器的地址。

用户通常使用主机名或域名来访问对方的计算机,而不是直接通过IP地址访问。因为与IP地址的一组纯数字相比,用字母配合数字的表示形式来指定计算机名更符合人类的记忆习惯。但要让计算机去理解名称,相对而言就变得困难了。因为计算机更擅长处理一长串数字。为了解决上述的问题,DNS服务应运而生。

2 什么是域名解析

DNS协议提供通过域名查找IP地址,或逆向从IP地址反查域名的服务。

DNS是一个网络服务器,我们的域名解析简单来说就是在 DNS上记录一条信息记录。

# 域名        # 服务器外网IP地址
baidu.com    220.114.23.56

3 DNS解析流程

那浏览器如何通过域名去查询URL对应的IP呢?如下图所示:


图2 DNS解析流程

名词解释:

  • 浏览器缓存:浏览器会按照一定的频率缓存DNS记录。
  • 操作系统缓存:如果浏览器缓存中找不到需要的DNS记录,那就去操作系统中找。
  • 路由缓存:路由器也有DNS缓存。
  • ISP的DNS服务器:ISP是互联网服务提供商(Internet Service Provider)的简称,ISP有专门的 DNS服务器应对DNS查询请求。
  • 根服务器:ISP的DNS服务器还找不到的话,它就会向根服务器发出请求,进行递归查询(DNS服务器先问根域名服务器.com域名服务器的IP地址,然后再问.baidu域名服务器,依次类推)。

浏览器通过向DNS服务器发送域名,DNS服务器查询到与域名相对应的IP地址,然后返回给浏览器,浏览器再将IP地址打在协议上,同时请求参数也会在协议搭载,然后一并发送给对应的服务器。接下来介绍向服务器发送HTTP请求阶段,HTTP请求分为三个部分:TCP三次握手、HTTP请求响应信息、关闭TCP连接。

0x3 TCP三次握手

在客户端发送数据之前会发起TCP三次握手用以同步客户端和服务端的序列号和确认号,并交换TCP窗口大小信息。


图3 TCP三次握手时序图

TCP三次握手的过程如下:

客户端发送一个带SYN=1,Seq=X的数据包到服务器端口(第一次握手,由浏览器发起,告诉服务器我要发送请求了)

服务器发回一个带SYN=1,Ack=X+1,Seq=Y的响应包以示传达确认信息(第二次握手,由服务器发起,告诉浏览器我准备接受了,你赶紧发送吧)

客户端再回传一个带Ack=Y+1,Seq=Z的数据包,代表“握手结束”(第三次握手,由浏览器发送,告诉服务器,我马上就发了,准备接受吧)

为啥需要三次握手?

谢希仁著《计算机网络》中讲“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。

0x4 HTTP请求

TCP三次握手结束后,开始发送HTTP请求报文。请求报文由请求行(Request Line)、请求头(Header)、请求体三个部分组成,如下图所示:


图4 HTTP请求报文结构

1 请求行包含请求方法、URL、协议版本

请求方法包含 8 种:GETPOSTPUTDELETEPATCHHEADOPTIONSTRACE

URL即请求地址,由<协议>://<主机>:<端口>/<路径>?<参数>组成

协议版本即HTTP版本号

POST /img/bd_logo1.png HTTP/1.1

以上代码中POST为请求方法,/img/bd_logo1.png为URL,HTTP/1.1代表协议和协议的版本。

2 请求头包含请求的附加信息,由关键字/值对组成,每行一对,关键字和值用英文冒号:分隔。

请求头部通知服务器有关于客户端请求的信息。它包含许多有关的客户端环境和请求正文的有用信息。其中比如:Host是主机名。

3 请求体

可以承载多个请求参数的数据,包含回车符、换行符和请求数据,并不是所有请求都具有请求数据。

name=tom&password=1234&realName=tomson

上面代码,承载着name、password、realName三个请求参数。

0x5 HTTP响应

1 服务器

服务器是网络环境中的高性能计算机,它侦听网络上的其他计算机(客户机)提交的服务请求,并提供相应的服务,比如网页服务、文件下载服务、邮件服务、视频服务。而客户端主要的功能是浏览网页、看视频、听音乐等等,两者截然不同。

每台服务器上都会安装处理请求的应用——WebServer。常见的WebServer产品有apache、nginx、IIS或Lighttpd等。

webserver担任管控的角色,对于不同用户发送的请求,会结合配置文件,把不同请求委托给服务器上处理相应请求的程序进行处理(例如CGI脚本、JSP脚本、Servlets、ASP脚本、服务器端JavaScript或者一些其它的服务器端技术等),然后返回后台程序处理产生的结果作为响应。


图5 服务器和客户端区别

2 MVC后台处理阶段

后台开发现在有很多框架,但大部分都还是按照MVC设计模式进行搭建的。


图6 MVC架构

MVC是一个设计模式,将应用程序分成三个核心部件:模型(Model)、视图(View)、控制器(Controller),它们各自处理自己的任务,实现输入、处理和输出的分离。

  • 视图(View)
    • 它是提供给用户的操作界面,是程序的外壳。
  • 模型(Model)
    • 模型主要负责数据交互。在MVC的三个部件中,模型拥有最多的处理任务。一个模型能为多个视图提供数据。
  • 控制器(Controller)
    • 它负责根据用户从“视图层”输入的指令,选取“模型层”中的数据,然后对其进行相应的操作,产生最终结果。控制器属于管理者角色,从视图接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示模型处理返回的数据。

这三层是紧密联系在一起的,但又是互相独立的,每一层内部的变化不影响其他层。每一层都对外提供接口(Interface),供上面一层调用。

至于这一阶段发生什么?简而言之,首先浏览器发送过来的请求先经过控制器,控制器进行逻辑处理和请求分发,接着会调用模型,这一阶段模型会获取Redis以及MySQL的数据,获取数据后将渲染好的页面,响应信息会以响应报文的形式返回给客户端,最后浏览器通过渲染引擎将网页呈现在用户面前。

3 HTTP响应报文

响应报文由响应行(RequestLine)、响应头部(Header)、响应主体三个部分组成。如下图所示:


图7 HTTP响应

响应行包含:协议版本,状态码,状态码描述。

状态码规则如下:

  • 1xx:指示信息——表示请求已接收,继续处理。
  • 2xx:成功——表示请求已被成功接收、理解、接受。
  • 3xx:重定向——要完成请求必须进行更进一步的操作。
  • 4xx:客户端错误——请求有语法错误或请求无法实现。
  • 5xx:服务器端错误——服务器未能实现合法的请求。

响应头部包含响应报文的附加信息,由名/值对组成。

响应主体包含回车符、换行符和响应返回数据,并不是所有响应报文都有响应数据。

0x6 浏览器解析渲染页面

浏览器拿到响应文本HTML后,接下来介绍下浏览器渲染机制。


图8 浏览器渲染机制

浏览器解析渲染页面分为一下五个步骤:

  • 根据HTML解析出DOM树;
  • 根据CSS解析生成CSS规则树;
  • 结合DOM树和CSS规则树,生成渲染树;
  • 根据渲染树计算每一个节点的信息;
  • 根据计算好的信息绘制页面。

1 根据HTML解析DOM树

根据HTML的内容,将标签按照结构解析成为DOM树,DOM树解析的过程是一个深度优先遍历。即先构建当前节点的所有子节点,再构建下一个兄弟节点。

在读取HTML文档,构建DOM树的过程中,若遇到script标签,则DOM树的构建会暂停,直至脚本执行完毕。

2 根据CSS解析生成CSS规则树

解析CSS规则树时js执行将暂停,直至CSS规则树就绪。

浏览器在CSS规则树生成之前不会进行渲染。

3 结合DOM树和CSS规则树,生成渲染树

DOM树和CSS规则树全部准备好了以后,浏览器才会开始构建渲染树。

精简CSS并可以加快CSS规则树的构建,从而加快页面相应速度。

4 根据渲染树计算每一个节点的信息(布局)

布局:通过渲染树中渲染对象的信息,计算出每一个渲染对象的位置和尺寸

回流:在布局完成后,发现了某个部分发生了变化影响了布局,那就需要倒回去重新渲染。

5 根据计算好的信息绘制页面

绘制阶段,系统会遍历呈现树,并调用呈现器的“paint”方法,将呈现器的内容显示在屏幕上。

重绘:某个元素的背景颜色,文字颜色等,不影响元素周围或内部布局的属性,将只会引起浏览器的重绘。

回流:某个元素的尺寸发生了变化,则需重新计算渲染树,重新渲染。

0x7 断开连接

当数据传送完毕,需要断开TCP连接,此时发起TCP四次挥手。


图9 TCP四次挥手

  • 发起方向被动方发送报文,Fin、Ack、Seq,表示已经没有数据传输了,并进入FIN_WAIT_1状态。
    第一次挥手:由浏览器发起的,发送给服务器,我请求报文发送完了,你准备关闭吧。
  • 被动方发送报文,Ack、Seq,表示同意关闭请求,此时主机发起方进入FIN_WAIT_2状态。
    第二次挥手:由服务器发起的,告诉浏览器,我请求报文接受完了,我准备关闭了,你也准备吧。
  • 被动方向发起方发送报文段,Fin、Ack、Seq,请求关闭连接,并进入LAST_Ack状态。
    第三次挥手:由服务器发起,告诉浏览器,我响应报文发送完了,你准备关闭吧。
  • 发起方向被动方发送报文段,Ack、Seq,然后进入等待TIME_WAIT状态。被动方收到发起方的报文段以后关闭连接。
    发起方等待一定时间未收到回复,则正常关闭。
    第四次挥手:由浏览器发起,告诉服务器,我响应报文接受完了,我准备关闭了,你也准备吧。

0x8 参考

Tags