一次HTTP请求到浏览器呈现页面都发生了什么
抛去浏览器的内部基础机制和返回页面的渲染之类的不说,当从网络的角度来看其中的基本步骤:
1.浏览器查看缓存,如果请求的内容在缓存之中并且是在存活时限之内就会执行第10步
2.浏览器会向操作系统询问该请求对应的IP地址
操作系统开始寻找域名对应的IP地址并最终返回给浏览器。系统查找IP地址,一般先查看浏览器的缓存,如果缓存中没有请求域名对应的IP地址,就会去查找在本地的host文件中是否存在对应的IP,如果还找不到就会询问DNS服务器。
DNS解析过程
3.浏览器开始建立与服务器的TCP连接
HTTP的底层是依靠TCP来通信的,所以简单介绍一些TCP/IP协议:
TCP/IP 协议族里重要的一点就是分层。TCP/IP 协议族按层次分别分为以下 4 层:应用层、传输层、网络层和数据链路层。
应用层:应用层决定了向用户提供应用服务时通信的活动(如FTP,DNS,HTTP)。
传输层:传输层对上层应用层,提供处于网络连接中的两台计算机之间的数据传输。
在传输层有两个性质不同的协议:TCP(Transmission Control Protocol,传输控制协议和 UDP(User Data Protocol,用户数据报协议)。
网络层:网络层用来处理在网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(所谓的传输路线)到达对方计算机,并把数据包传送给对方。
链路层:用来处理连接网络的硬件部分。包括控制操作系统、硬件的设备驱动NIC(Network Interface Card,网络适配器,即网卡),及光纤等物理可见部分(还包括连接器等一切传输媒介)。硬件上的范畴均在链路层的作用范围之内。
下图是TCP/IP的信息流:
TCP/IP信息流
HTTP通信是基于TCP/IP协议的,因此在通信之前会与目标服务器建立TCP连接,TCP为了保证可靠性,会进行三次握手,确认双方正式建立连接。
第一次握手:建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;
第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。
三次握手
三次握手
4.浏览器通过TCP连接发送HTTP请求
TCP连接建立后就可以开始发送HTTP报文了,由于底层通信使用了TCP/IP协议,因此HTTP报文在客户端会被层层包装添加TCP/IP协议中每一层的首部信息,直到被包装后的请求内容到达服务器端。服务器端接收到信息后又会逆向层层解包直到得到原本的HTTP报文。
HTTP通过TCP/IP信息流
5.服务器接收到请求后对请求做出处理,然后返回HTTP response。
一般来说,服务器接收到请求会根据请求的路径寻找一个可以处理该请求的程序。用MVC框架来解释就是:根据请求的路径找到对应处理请求的controller,之后控制器会调用业务逻辑处理请求,然后返回一个Model,之后通过视图解析器的包装最终变成一个response然后通过已经建立好的TCP连接以同样的传输方式返回给浏览器。
6.浏览器接收到HTTP响应,选择关闭TCP连接,或者继续维持等待下一次请求的发生如果选择关闭连接,会进行TCP的四次挥手
第一次挥手:主机1(可以使客户端,也可以是服务器端),设置Sequence Number,向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;
第二次挥手:主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,Acknowledgment Number为Sequence Number加1;主机1进入FIN_WAIT_2状态;主机2告诉主机1,我“同意”你的关闭请求;
第三次挥手:主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入LAST_ACK状态;
第四次挥手:主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。
四次挥手
7.浏览器检查收到的响应的状态码
浏览器检查响应是否是一个重定向响应或者是一个需要特殊处理的响应(3xx的状态码),或者是需要重新认证(401状态码),或者错误(4xx和5xx状态码)等;浏览器会和正常的响应(2xx)相区别并作出不同的应对。
HTTP状态码
8.如果缓存是可用的,响应会被放入缓存
9.浏览器对响应进行解码(通常使用gzip)
10.浏览器真正决定如何处理这个响应
判断响应是什么文件,比如是HTML页面或者是图片,又或者是声音文件。如果是页面,浏览器会渲染并呈现给用户,又或者是提供认证或者是下载的窗口等,取决于浏览器收到了什么类型的响应。
下面的两个图可以辅助理解这个过程:
HTTP工作流程
各个协议之间的关系
如果请求使用了HTTPS那么流程会有什么不同?
HTTPS实际上是为了保证HTTP的安全性而在HTTP的基础上加入加密处理和认证等机制。通常,HTTP直接和TCP通信。当使用SSL时,则演变成先和SSL通信,再由SSL和TCP通信了。简言之,所谓HTTPS,其实就是身披SSL协议这层外壳HTTP。
HTTP和HTTPS
实际上不管怎么称呼,实现安全性的一种通用的措施就是对通信内容进行加密。那么最常用的两种加密方式无非是对称加密和非对称加密。对称加密即双方持有相同的密钥进行加密和解密,但是在网络环境下如何传输密钥就成了问题。于是出现了非对称加密通信双方持有对方的公钥和自己的私钥,使用公钥加密,私钥解密。很明显对称加密的效率要比非对称加密高,因此HTTPS使用了混合加密的方式。用非对称加密传输共享密钥,然后用共享密钥进行对称加密传输。
因此HTTPS的通信过程大概如下图所示
HTTPS通信过程
步骤 1:客户端通过发送Client Hello报文开始SSL通信。报文中包含客户端支持的SSL的指定版本、加密组件(Cipher Suite)列表(所使用的加密算法及密钥长度等)。
步骤 2: 服务器可进行SSL通信时,会以Server Hello报文作为应答。和客户端一样,在报文中包含SSL版本以及加密组件。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。
步骤 3: 之后服务器发送Certificate报文。报文中包含公开密钥证书。
步骤 4: 最后服务器发送Server Hello Done报文通知客户端,最初阶段的 SSL 握手协商部分结束。
步骤 5: SSL 第一次握手结束之后,客户端以Client Key Exchange报文作为回应。报文中包含通信加密中使用的一种被称为Pre-mastersecret的随机密码串。该报文已用步骤3中的公开密钥进行加密。
步骤 6: 接着客户端继续发送Change Cipher Spec报文。该报文会提示服务器,在此报文之后的通信会采用Pre-master secret密钥加密。
步骤 7: 客户端发送Finished报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准。
步骤 8: 服务器同样发送Change Cipher Spec报文。
步骤 9: 服务器同样发送Finished报文。
步骤 10: 服务器和客户端的Finished报文交换完毕之后,SSL连接就算建立完成。当然,通信会受到SSL的保护。从此处开始进行应用层协议的通信,即发送HTTP请求。
步骤 11: 应用层协议通信,即发送HTTP响应。
步骤 12: 最后由客户端断开连接。断开连接时,发送close_notify报文。上图做了一些省略,这步之后再发送TCP FIN报文来关闭与TCP的通信。
下面的图对上面的流程做了一个补充:
HTTPS通信协商
也就是流程中从第1步到第9步都是通过协商确定对称加密的过程,第九步结束之后,通信双方都确定了使用对称加密,确认双方使用了同一个共享的密钥,之后的通信就是在对称加密基础上的通信了。
参考:
图解HTTP