浏览器工作原理:HTTP

93 阅读7分钟

这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

HTTP简介

  • 超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。通常用于向浏览器发送请求,获取前端代码、图片、视频等资源。

浏览器发起HTTP请求步骤

  1. 构建请求:构建请求行信息,准备发起网络请求

image.png 2. 查找缓存: 在发起请求前,浏览器会先查看缓存中是否已有要请求的文件,如果有就会拦截请求,返回缓存中的文件,同时结束请求(缓存中的文件是本地资源的副本)。缓存没有的话,直接进入网络请求。

  • 优点:缓解服务器的压力(大量数据请求也会使服务器瘫痪),同时因为请求时间变短达到提升性能的作用
  1. 准备IP地址和端口:浏览器使用HTTP 协议作为应用层协议,用来封装请求的文本信息;并使用 TCP/IP 作传输层协议将它发到网络上,所以在 HTTP 工作开始之前,浏览器需要通过 TCP 与服务器建立连接。 HTTP 的内容是通过 TCP 的传输数据阶段来实现的

image.png

补充: IP地址是一长串数字不便记忆,因此产生DNS(Domain Name System域名系统)负责把域名和 IP 地址做一一映射关系。

(1)浏览器会请求 DNS 返回域名对应的 IP(这里也采用缓存存储)

(2)通常情况下,如果 URL 没有特别指明端口号,那么 HTTP 协议默认是 80 端口。

  1. 等待 TCP 队列:由于Chrome同一个域名同时最多只能建立 6 个 TCP 连接,这样超出的请求就会处于等待状态直至进行中的请求完成才能进行TCP链接。

  2. 建立 TCP 连接:排队等待结束之后,终于和服务器握手了,在 HTTP 工作开始之前,浏览器通过 TCP 与服务器建立连接。 TCP的工作方式

  3. 发送 HTTP 请求:一旦建立了 TCP 连接,浏览器就可以和服务器进行通信了。

image.png 浏览器会向服务器发送请求行,它包括了请求方法请求 URI(Uniform Resource Identifier)和 HTTP 版本协议。(告诉服务器浏览器需要什么资源)

  • 常用的两种请求方法是:GET(取)/POST(发,数据是通过请求体来发送。)

  • 请求头把浏览器的一些基础信息告诉服务器。比如浏览器所使用的操作系统、浏览器内核等信息,以及当前请求的域名信息、浏览器端的 Cookie 信息等。

  1. 服务器端处理 HTTP 请求流程 (1) 返回请求

服务器处理结束返回数据给浏览器了。可以通过工具软件 curl 来查看返回请求数据,在控制台命令行中输入以下命令:

curl -i https://time.geekbang.org/

注意这里加上了-i是为了返回响应行、响应头和响应体的数据,返回的结果如下图所示,

image.png

  • 服务器会返回响应行,包括协议版本和状态码。

对于一些无法处理出错的信息,服务器会通过请求行的状态码来告诉浏览器它的处理结果,比如:最常用的状态码是 200,表示处理成功;如果没有找到页面,则会返回 404。

  • 服务器向浏览器发送响应头。响应头包含了服务器自身的一些信息,比如服务器生成返回数据的时间、返回的数据类型(JSON、HTML、流媒体等类型),以及服务器要在客户端保存的 Cookie 等信息。

  • 服务器就可以继续发送响应体的数据,通常,响应体就包含了 HTML 的实际内容。以上这些就是服务器响应浏览器的具体过程。 (2) 断开连接

  • 通常情况下,一旦服务器向客户端返回了请求数据,它就要关闭 TCP 连接。

  • 如果浏览器或者服务器在其头信息中加入了:Connection:Keep-Alive , TCP 连接在发送后将仍然保持打开状态,这样浏览器就可以继续通过同一个 TCP 连接发送请求。保持 TCP 连接可以省去下次请求时需要建立连接的时间,提升资源加载速度

  • 比如,一个 Web 页面中内嵌的图片就都来自同一个 Web 站点,如果初始化了一个持久连接,你就可以复用该连接,以请求其他资源,不需要重新建立新的 TCP 连接。

(3) 重定向

  • 当你在浏览器中打开 geekbang.org 后,你会发现最终打开的页面地址是 www.geekbang.org 这两个 URL 之所以不一样,是因为涉及到了一个重定向操作。 在控制台输入如下命令:(-I表示只需要获取响应头和响应行数据,而不需要获取响应体的数据)
curl -I geekbang.org

image.png 从图中你可以看到,响应行返回的状态码是 301,告诉浏览器,我需要重定向到另外一个网址,而需要重定向的网址正是包含在响应头的 Location 字段中,接下来,浏览器获取 Location 字段中的地址,并使用该地址重新导航。这里只有编写代码时设置了才能实现这种重定向。

1. 为什么很多站点第二次打开速度会很快?

第一次加载页面过程中,缓存了一些耗时的数据。

  • 数据:DNS 缓存页面资源缓存这两块数据是会被浏览器缓存的。

下面是缓存处理的过程:

image.png 从上图的第一次请求可以看出,当服务器返回 HTTP 响应头给浏览器时,浏览器是通过响应头中的 Cache-Control 字段来设置是否缓存该资源。通常,我们还需要为这个资源设置一个缓存过期时长,而这个时长是通过 Cache-Control 中的 Max-age 参数来设置的,比如上图设置的缓存过期时间是 2000 秒。 Cache-Control:Max-age=2000

  • 缓存资源还未过期的情况下, 如果再次请求该资源,会直接返回缓存中的资源给浏览器。

  • 过期了,浏览器则会继续发起网络请求,并且在 HTTP 请求头中带上:If-None-Match:"4f80f-13c-3a1xb12a"服务器收到请求头后,会根据If-None-Match 的值来判断请求的资源是否有更新。

  • 没有更新,就返回 304 状态码,缓存可以继续使用,不发送资源。

  • 资源有更新,服务器就直接返回最新资源给浏览器。

总结:网站把很多资源都缓存在了本地,浏览器缓存直接使用本地副本来回应请求,而不会产生真实的网络请求,从而节省了时间。同时,DNS 数据也被浏览器缓存了,省去了 DNS 查询环节。

2. 登录状态是如何保持的?

image.png

  • 如果服务器端发送的响应头内有 Set-Cookie 的字段,那么浏览器就会将该字段的内容保持到本地。当下次客户端再往该服务器发送请求时,客户端会自动在请求头中加入 Cookie 值后再发送出去。服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到该用户的状态信息。