一、什么是HTTP事务
一次完整的请求+响应被称为HTTP事务,在HTTP事务中有一系列的信息交换,这些信息交换是一个不可分割的整体,也就是说,要么所有的信息全部交换完,要么一次交换也不进行。(毕竟事务的特性搁那摆着)
HTTP事务有以下四个部分组成:
- 客户端与服务器建立连接。HTTP是基于TCP协议,这里的连接可以理解为TCP连接;如果我们只知道服务器的域名,还需要在建立连接前发起DNS解析,TCP的Socket通信需要服务器的IP地址;建立连接的过程需要三次握手。
- 客户端向服务器发送请求。在建立TCP连接之后,客户端给服务器发送一个HTTP请求报文,请求报文中包含有客户端需要的资源等信息,例如最简单的HTML文档。
- 服务器给客户端一个响应。服务器收到客户端的请求后,可以拒绝客户端的请求,也可以向客户端发送一个HTTP响应报文;这个响应中包含了客户端请求的HTML文档。
- 客户端与服务器断开连接。在客户端收到服务器响应后,可以选择与服务器断开连接,也可以选择继续保持连接(HTTP持续连接),以供下一个HTTP事务使用;客户端和服务器都可以发起关闭连接,关闭TCP连接需要四次挥手。
二、HTTP事务和浏览器的关系
在学习HTTP事务的过程中发现有的博客中的将HTTP事务解释为下面这几个步骤:
- 域名解析
- 发起TCP的3次握手
- 建立TCP连接后发起http请求
- 服务器端响应http请求,浏览器得到html代码
- 浏览器解析html代码,并请求html代码中的资源
- 浏览器对页面进行渲染呈现给用户
在最后一步中,大多文章都写的是浏览器渲染页面,然后就没了。个人理解,还是应该有关闭TCP连接这一步,在HTTP/1.1中HTTP报文中可以通过Connection:close
来关闭连接。
刚开始,我也比较疑惑,是不是应该加上浏览器渲染页面,如果加上这一步,浏览器到底是先渲染页面还是先关闭TCP连接呢? 不少网友认为在不考虑持续连接的前提下,服务端响应完HTTP请求后,就会断开连接,渲染是浏览器的事,和HTTP协议并没有关系。
如果有同样疑惑可以看一看这两篇文章:到底是浏览器渲染页面还是先关闭TCP连接 和 An HTTP Transaction
再者说,浏览器在HTTP事务中仅仅是运行在客户端上的一个软件,我们同样可以使用一些其他的方式来发起HTTP请求,例如使用 Fiddler 可以模拟HTTP请求,也可以通过网络编程来实现。而浏览器在HTTP响应之后将HTML文档渲染成页面反馈给了用户,这和HTTP事务关系不大。
如果有不同观点,感谢指正!
三、通过curl来查看HTTP事务过程
在Ubuntu环境下,可以使用 crul
来获取 www.baidu.com
的首页,然后可以通过 tcpdump
抓包工具来获取HTTP事务的信息交换过程。
curl
和 tcpdump
这俩命令可以使用 apt-get install
安装。
1、抓取主机www.baidu.com发送和接收的包,-f显示外部Internet地址:
tcpdump -f host www.baidu.com
2、使用curl获取www.baidu.com的首页
curl www.baidu.com
抓包记录中的 Flags 含义如下:
Tcpflags are some combination of S (SYN), F (FIN), P (PUSH), R (RST),U (URG), W (ECN CWR), E (ECN-Echo) or ‘.’ (ACK), or ‘none’
比如: Flags[S]同步SYN,Flags[S.]SYN确认报文
3、添加-A参数可以看到HTTP报文(百度首页的HTML文档作为响应体和HTTP响应报文一起发送回来):
sudo tcpdump -f -A host www.baidu.com