封装 TCP 数据包
浏览器得到目标服务器的 IP 地址后,根据 URL 中的端口可以知道端口号 (http 协议默认端口号是 80, https 默认端口号是 443),会准备 TCP 数据包。数据包的封装会经过下面的层层处理,数据到达目标主机后,目标主机会解析数据包,完整的请求和解析过程如下。
这里就不再详细介绍了,读者朋友们可以阅读 cxuan 的这篇文章 TCP/IP 基础知识详解详细了解。
浏览器与目标服务器建立 TCP 连接
在经过上述 DNS 和 ARP 查找流程后,浏览器就会收到一个目标服务器的 IP 和 MAC地址,然后浏览器将会和目标服务器建立连接来传输信息。这里可以使用很多种 Internet 协议,但是 HTTP 协议建立连接所使用的运输层协议是 TCP 协议。所以这一步骤是浏览器与目标服务器建立 TCP 连接的过程。
TCP 的连接建立需要经过 TCP/IP 的三次握手,三次握手的过程其实就是浏览器和服务器交换 SYN 同步和 ACK 确认消息的过程。
假设图中左端是客户端主机,右端是服务端主机,一开始,两端都处于CLOSED(关闭)
状态。
- 服务端进程准备好接收来自外部的 TCP 连接。然后服务端进程处于
LISTEN
状态,等待客户端连接请求。 - 客户端向服务器发出连接请求,请求中首部同步位 SYN = 1,同时选择一个初始序号 sequence ,简写 seq = x。SYN 报文段不允许携带数据,只消耗一个序号。此时,客户端进入
SYN-SEND
状态。 - 服务器收到客户端连接后,,需要确认客户端的报文段。在确认报文段中,把 SYN 和 ACK 位都置为 1 。确认号是 ack = x + 1,同时也为自己选择一个初始序号 seq = y。请注意,这个报文段也不能携带数据,但同样要消耗掉一个序号。此时,TCP 服务器进入
SYN-RECEIVED(同步收到)
状态。 - 客户端在收到服务器发出的响应后,还需要给出确认连接。确认连接中的 ACK 置为 1 ,序号为 seq = x + 1,确认号为 ack = y + 1。TCP 规定,这个报文段可以携带数据也可以不携带数据,如果不携带数据,那么下一个数据报文段的序号仍是 seq = x + 1。这时,客户端进入
ESTABLISHED (已连接)
状态 - 服务器收到客户的确认后,也进入
ESTABLISHED
状态。
这样三次握手建立连接的阶段就完成了,双方可以直接通信了。
浏览器发送 HTTP 请求到 web 服务器
一旦 TCP 连接建立完成后,就开始直接传输数据办正事了!此时浏览器会发送 GET
请求,要求目标服务器提供 maps.google.com 的网页,如果你填写的是表单,则发起的是 POST
请求,在 HTTP 中,GET 请求和 POST 请求是最常见的两种请求,基本上占据了所有 HTTP 请求的九成以上。
除了请求类型外,HTTP 请求还包含很多很多信息,最常见的有 Host、Connection 、User-agent、Accept-language 等
首先 Host 表示的是对象所在的主机。Connection: close
表示的是浏览器需要告诉服务器使用的是非持久连接
。它要求服务器在发送完响应的对象后就关闭连接。User-agent
: 这是请求头用来告诉 Web 服务器,浏览器使用的类型是 Mozilla/5.0
,即 Firefox 浏览器。Accept-language
告诉 Web 服务器,浏览器想要得到对象的法语版本,前提是服务器需要支持法语类型,否则将会发送服务器的默认版本。下面我们针对主要的实体字段进行介绍(具体的可以参考 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers MDN 官网学习)
HTTP 的请求标头分为四种: 通用标头
、请求标头
、响应标头
和 实体标头
。
这四种标头又分别有很多内容,如果你想要深入理解一下关于 HTTP 请求头的相关内容,可以参考 cxuan 的这篇文章
服务器处理请求并发回一个响应
这个服务器包含一个 Web 服务器,也就是 Apache 服务器,服务器会从浏览器接收请求并将其传递给请求处理程序并生成响应。
请求处理程序也是一个程序,它一般是用 .net 、php、ruby 等语言编写,用于读取请求,检查请求内容,cookie,必要时更新服务器上的信息的这么一个程序。它会以特定的格式比如 JSON、XML、HTML 组合响应。
服务器发送回一个 HTTP 响应
服务器响应包含你请求的网页以及状态代码,压缩类型(Content-Encoding),如何缓存页面(Cache-Control),要设置的 cookie,隐私信息等。
比如下面就是一个响应体
关于深入理解 HTTP 请求和响应,可以参考这篇文章
浏览器显示 HTML 的相关内容
浏览器会分阶段显示 HTML 内容。首先,它将渲染裸露的 HTML 骨架。然后它将检查 HTML 标记并发送 GET 请求以获取网页上的其他元素,例如图像,CSS 样式表,JavaScript 文件等。这些静态文件由浏览器缓存,因此你再次访问该页面时,不用重新再请求一次。最后,您会看到 maps.google.com 显示的内容出现在你的浏览器中。