爬虫基础(HTTP协议工作原理)

270 阅读11分钟

在面试之前一定需要了解的内容:

  1. OSI与TCP/IP协议
  2. 三次握手和四次挥手
  3. HTTP协议原理
  4. 抓包工具原理

HTTP协议工作原理

1、浏览器构建请求行

当浏览器发起HTTP请求时,请求行(Request Line)是其中的第一行,用于描述请求的基本信息。请求行由三部分组成:请求方法(Request Method)、请求URL(Request URL)和协议版本(Protocol Version)。

请求方法定义了请求的行为,常见的请求方法有GET、POST、PUT、DELETE等。请求URL指定了请求的资源地址,可以是绝对URL或相对URL。协议版本指定了请求所使用的HTTP协议的版本,例如HTTP/1.1。

因此,浏览器构建请求行的过程就是确定请求方法、请求URL和协议版本,并将它们按照一定的格式组合成请求行。例如,一条GET请求的请求行可能长这样:

GET /index.html HTTP/1.1

其中,GET是请求方法,/index.html是请求URL,HTTP/1.1是协议版本。

2、查找强缓存

强缓存是浏览器缓存机制的一种,它可以使浏览器在请求资源时不再向服务器发起请求,而是直接使用本地缓存的资源。在查找强缓存时,浏览器首先会检查本地缓存中是否存在请求的资源,并判断是否过期。

判断缓存是否过期的方式有两种,分别是Expires和Cache-Control。Expires是HTTP/1.0提出的一种缓存过期机制,它通过在响应头中设置一个过期时间来指定该资源何时过期。浏览器在检查缓存时会比较当前时间与Expires的时间戳,如果当前时间小于过期时间,则缓存有效。但是Expires存在一些问题,例如缓存过期时间依赖于客户端和服务器的时钟不一致问题。

为了解决这些问题,HTTP/1.1提出了一种新的缓存控制机制——Cache-Control。Cache-Control通过在响应头中设置各种指令来控制缓存行为,包括max-age、no-cache、no-store等。其中,max-age指令用于设置缓存的最长有效时间,浏览器在检查缓存时会比较当前时间与资源缓存时间加上max-age的时间戳,如果当前时间小于等于该时间戳,则缓存有效。

如果浏览器检查到缓存资源没有过期,则直接从缓存中读取资源,不再向服务器发送请求。这样可以减少网络请求,提高页面加载速度。

3、浏览器向DNS服务器请求解析该URL中的域名所对应的IP地址

当浏览器需要向某个URL请求资源时,它首先需要将该URL中的域名解析成对应的IP地址。这个过程需要通过DNS服务器来完成。

浏览器会首先检查本地缓存是否有该域名对应的IP地址。如果本地缓存中有,则直接使用缓存中的IP地址;如果没有,则浏览器会向本地DNS解析器发起请求。本地DNS解析器会查询自己的缓存,如果有该域名对应的IP地址,则返回给浏览器;如果没有,则向根DNS服务器发起请求。

根DNS服务器返回给本地DNS解析器一个TLD(Top Level Domain)服务器的IP地址,TLD服务器通常是.com、.net、.org等域名的服务器。本地DNS解析器随即向TLD服务器发起请求,TLD服务器返回给本地DNS解析器下一级DNS服务器的IP地址。此时,本地DNS解析器会向该下一级DNS服务器发起请求,以此类推,直到找到域名对应的IP地址。

一旦本地DNS解析器找到了域名对应的IP地址,它会将该IP地址缓存起来,同时返回给浏览器。浏览器在接收到IP地址后,便可以向该IP地址所对应的服务器发起请求,获取资源。

4、根据IP地址和端口号,与服务器建立TCP连接

在通过DNS服务器解析出服务器的IP地址后,浏览器需要与该IP地址所对应的服务器建立TCP连接,以便发送HTTP请求和接收响应。

TCP是一种可靠的面向连接的协议,它可以提供错误检测、流量控制、拥塞控制等功能,确保数据传输的可靠性和完整性。建立TCP连接的过程需要进行三次握手,具体步骤如下:

  1. 客户端(浏览器)向服务器发送一个SYN(同步)报文,其中包含客户端的初始序列号。这个报文用于请求建立连接。

  2. 服务器接收到SYN报文后,向客户端发送一个SYN-ACK报文,其中包含服务器的初始序列号以及确认号(客户端序列号+1)。这个报文用于确认客户端请求,并提供服务器的初始序列号。

  3. 客户端接收到服务器的SYN-ACK报文后,向服务器发送一个ACK(确认)报文,其中包含客户端的确认号(服务器序列号+1)。这个报文用于确认服务器的响应,建立连接。

完成三次握手后,TCP连接就建立成功了,客户端和服务器可以开始进行数据传输。需要注意的是,TCP连接是一种有状态的连接,浏览器需要在每个HTTP请求中发送TCP连接的相关信息,以便服务器正确处理请求。

5、浏览器发出读取文件的HTTP请求

当TCP连接建立成功后,浏览器就可以向服务器发出HTTP请求,请求需要的资源。

HTTP请求由请求行、请求头和请求体三个部分组成。其中,请求行包含请求方法、请求的URL和HTTP协议的版本,用于指定请求的行为和目标资源。读取文件的HTTP请求通常使用的是GET方法,具体的请求行格式如下:

GET /path/to/file HTTP/1.1

其中,/path/to/file是需要请求的文件路径。HTTP/1.1是HTTP协议的版本号,表示使用的是HTTP协议的1.1版本。

除了请求行外,HTTP请求还包括请求头和请求体。请求头包含了关于请求的附加信息,如请求的来源、Accept-Encoding等。请求体则包含了请求的数据,通常在GET请求中为空。

例如,浏览器可以向服务器发出如下的HTTP请求,请求读取位于服务器根目录下的index.html文件:

GET /index.html HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
If-Modified-Since: Sat, 01 May 2021 00:00:00 GMT
If-None-Match: "etag12345"

这个请求中,Host头指定了请求的目标服务器,User-Agent头指定了浏览器的类型和版本,Accept头指定了浏览器能够接受的资源类型,Accept-Encoding头指定了浏览器能够接受的压缩方式,If-Modified-SinceIf-None-Match头用于实现缓存功能,请求体为空。

6、服务器对浏览器请求做出响应,并把对应的HTML文本发送给浏览器

在接收到浏览器发出的HTTP请求后,服务器会根据请求的内容和参数生成相应的HTTP响应,然后将响应发送回浏览器。

HTTP响应由响应行、响应头和响应体三个部分组成。其中,响应行包含了HTTP协议的版本、响应状态码和状态消息。响应头包含了与响应相关的附加信息,如响应的日期、服务器类型、内容类型等。响应体则包含了服务器返回的具体数据,如HTML文本、图片、视频等。

例如,如果浏览器请求读取位于服务器根目录下的index.html文件,服务器可能会返回如下的HTTP响应:

HTTP/1.1 200 OK
Date: Sat, 08 May 2023 12:00:00 GMT
Server: Apache/2.4.6 (CentOS)
Last-Modified: Fri, 07 May 2023 12:00:00 GMT
ETag: "etag12345"
Content-Length: 1234
Content-Type: text/html; charset=UTF-8

<!DOCTYPE html>
<html>
<head>
  <title>My Web Page</title>
</head>
<body>
  <h1>Welcome to my web page!</h1>
  <p>This is some sample text.</p>
</body>
</html>

这个响应中,响应行指示响应的状态码为200 OK,表示服务器已成功处理请求。响应头包含了响应的日期、服务器类型、文件的最后修改时间、文件的ETag(用于实现缓存功能)、内容长度和内容类型。响应体中则包含了服务器返回的HTML文本,用于在浏览器中显示网页内容。

浏览器收到服务器的响应后,会根据响应头中的信息对响应进行处理,如判断响应的状态码、解析响应的内容类型、缓存响应等。最终,浏览器会将HTML文本渲染到页面上,显示给用户。

7、释放TCP连接(如果keep-alive为关闭状态)

在HTTP/1.1中,除非特别声明,否则默认情况下使用持久连接(Keep-Alive)。这意味着一旦建立了TCP连接并完成HTTP请求和响应交换后,连接将保持打开状态,可以在后续的HTTP请求中重复使用。

但是,如果在HTTP头部没有明确指定持久连接,或者指定了“Connection: close”头部,则表示在该请求完成后,连接将被关闭,需要重新建立TCP连接才能发送下一个HTTP请求。此时,浏览器和服务器都会关闭连接,释放资源。

在释放TCP连接时,浏览器和服务器都会执行类似的操作,包括向对方发送TCP关闭连接信号(FIN),等待对方的确认信号(ACK),关闭本地套接字等。释放TCP连接的过程一般比较快速,通常只需要几个网络包的时间。

需要注意的是,如果服务器支持持久连接,并且浏览器在请求头部中明确指定了“Connection: keep-alive”头部,则连接将保持打开状态,可以在后续的HTTP请求中重复使用。这可以减少建立TCP连接的次数,提高请求效率。在这种情况下,连接会一直保持打开状态,直到达到某个预设的时间限制或者服务器端关闭连接。

8、浏览器将HTML文本显示为网页

当浏览器接收到服务器返回的HTML文本后,会将其解析为DOM树。DOM树是一个基于文档结构的对象模型,它代表了整个HTML文档的结构,包括HTML标签、文本、属性等。

浏览器解析HTML文本的过程可以分为三个步骤:解析、构建和渲染。

  • 解析:浏览器会将HTML文本解析为DOM树。在解析过程中,浏览器会忽略掉一些无用的空白字符,并尝试将不符合规范的HTML标记转换为DOM元素。

  • 构建:在构建过程中,浏览器会将DOM树和CSS样式表结合起来,构建出一个新的结构化对象模型——渲染树。渲染树是一种结合了DOM树和CSS样式的树形结构,它包含了所有需要渲染的节点,但不包含一些不需要渲染的节点(比如display属性值为none的节点)。

  • 渲染:在渲染过程中,浏览器会将渲染树转换为屏幕上的像素,通过GPU进行绘制,最终呈现给用户。

需要注意的是,解析、构建和渲染过程是并行执行的,这样可以提高渲染的速度和效率。在解析的过程中,如果遇到需要下载的资源,比如图片、脚本等,浏览器会将其加入到下载队列中,然后继续解析后续的内容。一旦资源下载完成,浏览器会尽快将其插入到渲染树中进行渲染,这样可以避免等待时间过长造成的卡顿现象。

总之,浏览器将HTML文本显示为网页的过程是一个复杂的过程,需要经历多个步骤,包括解析、构建和渲染。这个过程中,浏览器会尽可能地提高渲染的速度和效率,使得用户可以快速地浏览网页内容。