【计算机网络】HTTP协议详解&实战抓包分析教程

1.HTTP简介

HTTP(Hypertext Transfer Protocol)即超文本传输协议,是互联网上应用最为广泛的一种网络协议,主要用于从WWW服务器传输超文本到本地浏览器的传输协议。它是基于客户端-服务器模型的,目的是允许浏览器(或其他HTTP客户端)从Web服务器请求资源,并且服务器能够将这些资源传回给客户端。

主要特性:

  • 无状态:HTTP协议是无状态的,这意味着每个请求都是独立的,服务器不保留关于客户的任何信息(如 cookies 可以用来维护会话状态)。
  • 媒体独立:可以传输任意类型的数据对象,不限于文本,图像、视频等多媒体文件同样可以传输。
  • 简单快速:客户端向服务器请求服务时,只需传送请求方法和路径。常用的方法有GET、POST等。
  • 灵活:HTTP允许传输数据的内容类型多样,通过Content-Type加以标记。
  • 无连接:限制每次连接只处理一个请求,之后连接就会关闭,但实际应用中常通过Keep-Alive机制保持连接打开,以便多个请求复用。

2.HTTP报文的结构

大家应该都听说过HTTP请求和HTTP响应.因此HTTP报文也分为请求报文和响应报文,但是请求报文和响应报文的结构是一样的.
如图:
image-20240509233021387
请求报文和响应报文虽然结构是一样的,但是报文首部是不同的

在请求报文中,HTTP报文首部是由方法,URI,HTTP版本和HTTP首部字段构成

image-20240509234659100

在响应报文中,HTTP报文首部是由HTTP版本,状态码和HTTP首部字段构成

image-20240509234458286

3.HTTP协议中空行的作用

因为 HTTP 协议并没有规定报头部分的键值对有多少个. 空行就相当于是 “报头的结束标记”, 或者

是 “报头和正文之间的分隔符”.

HTTP 在传输层依赖 TCP 协议, TCP 是面向字节流的. 如果没有这个空行, 就会出现 “粘包问题”.

4.uri和url的区别

URI(Uniform Resource Identifier,统一资源标识符)和URL(Uniform Resource Locator,统一资源定位符)都是用于标识网络资源的字符串,但它们在概念和用途上有所区别:

  1. URI 是一个更广泛的概念,它是用于标识互联网上或计算机系统中任何资源的字符串。URI 包括了定位资源的地址(即URL),也包括仅用于命名或识别资源但不提供直接访问方式的标识符(例如URN,Uniform Resource Name)。URI 的目的是确保每一个资源都有一个唯一的标识,无论这个资源是可以获取的还是仅仅被命名的。
  2. URL 是 URI 的一个子集,它是一种特定类型的 URI,不仅标识了资源,还提供了定位和访问该资源的方法。URL 包含了访问资源所需的全部信息,比如协议类型(http、https)、主机名、路径(/path/to/resource)以及可能的查询字符串(?key=value)等。简而言之,当你能通过某个地址在互联网上找到一个资源时,那个地址就是一个以及可能的查询字符串(?key=value)等。简而言之,当你能通过某个地址在互联网上找到一个资源时,那个地址就是一个) URL。

总结来说,所有 URL 都是 URI,因为它们都能标识资源,但不是所有的 URI 都是 URL,有的 URI 只是用来命名资源而不提供定位信息(例如URN)。在实际应用中,我们通常所说的网址就是 URL,它是 URI 实际应用中最常见的一种形式。

5.HTTP请求

5.1 HTTP请求方法

HTTP协议定义了一系列请求方法,用于指示客户端希望服务器对资源执行的操作。以下是HTTP/1.1中定义的8种主要请求方法,每种方法都有其特定的用途和特点:

  1. GET:用于请求指定的资源。请求的数据会附加在URL(query string)之后,以查询字符串的形式传递。GET请求是最常见的,用于获取资源,应是安全和幂等的。
  2. POST:用于向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据包含在请求正文(body)中,POST请求不是幂等的,多次请求可能会产生不同结果。
  3. PUT:用于替换指定资源的全部内容。客户端提供更新后的资源,要求服务器存储。此方法是幂等的,多次执行具有相同效果。
  4. DELETE:请求服务器删除指定的资源。此方法也是幂等的,多次请求删除同一资源的结果是一致的。
  5. HEAD:类似于GET方法,但服务器只返回响应头,不返回响应主体,用于检查资源的存在性、类型、大小等元数据,而不需要传输整个内容。
  6. OPTIONS:用于获取服务器支持的HTTP请求方法和其他通信选项,可用于检测服务器功能或测试权限。
  7. TRACE:客户端发送一个请求,服务器会将收到的请求原样返回,主要用于诊断和测试目的,查看请求在到达服务器前经过的路径上的改动。
  8. CONNECT:用于建立一个到由目标资源标识的服务器的TCP连接通道,通常用于代理服务器中,实现对HTTPS等需要通过隧道协议进行安全传输的请求。

关于Query String和Param(Parameters)

  • 查询字符串(Query String)是指URL中跟在问号(?)后面的部分,用于携带额外的信息,特别是作为HTTP GET请求的一部分传递参数给服务器。它由一系列键值对组成,键值对之间用等号(=)连接,不同的键值对之间用和号(&)分隔。例如,在URL https://example.com/search?q=query+term&sort=date 中,q=query+termsort=date 就是查询字符串中的两个参数。

  • 参数(Params)是查询字符串中具体键值对的统称。在上述例子中,qsort 是参数名,query+termdate 是对应的参数值。这些参数让服务器知道客户端请求的具体细节,比如搜索关键词、排序方式等。

5.2 HTTP请求报头

HTTP请求报头(Request Headers)是一系列键值对,位于请求行之后,请求主体之前,每一行代表一个报头字段。

以下是我用Fiddler抓的一个包

image-20240510142355886

具体内容如下:

GET https://www.baidu.com/ HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
sec-ch-ua: "Chromium";v="124", "Microsoft Edge";v="124", "Not-A.Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cookie: BIDUPSID=DD7326D9CB3E780AE232E272F9988EF1; PSTM=1700320963; BAIDUID=CB65E88DF6D23B274067D86F39E33F91:FG=1; H_WISE_SIDS=40171_40369_40376_40398_40416_40305_40458_39662_40511_40512_60044_60026_60035_60048_60058; H_WISE_SIDS_BFESS=40171_40369_40376_40398_40416_40305_40458_39662_40511_40512_60044_60026_60035_60048_60058; BAIDUID_BFESS=CB65E88DF6D23B274067D86F39E33F91:FG=1; COOKIE_SESSION=130_0_8_3_5_14_1_1_8_6_1_3_56_0_0_0_1713166585_0_1713181572%7C9%23580281_10_1665372810%7C4; BAIDU_WISE_UID=wapp_1713714319309_20; H_PS_PSSID=40305_40080_60138_60186; BDUSS=2R5UzNPZzZ3ai1kNVlXcEZjVWc4ZnctT3ZVRmdGQllvOXpCb0JZNGljanFmMWxtRVFBQUFBJCQAAAAAAAAAAAEAAAA1MYH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOryMWbq8jFmc; BDUSS_BFESS=2R5UzNPZzZ3ai1kNVlXcEZjVWc4ZnctT3ZVRmdGQllvOXpCb0JZNGljanFmMWxtRVFBQUFBJCQAAAAAAAAAAAEAAAA1MYH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOryMWbq8jFmc; ZFY=DAt6xuFJrVO9Vof3C8Wq3xMauOxCp4CYAj4HYxdRdyg:C

第一行GET https://www.baidu.com/ HTTP/1.1是方法,URI,HTTP版本.就不多说了

  • Host: www.baidu.com:请求的服务器的域名和(可选的)端口号,用于虚拟主机的识别。没写端口就是默认值
    • HTTP默认端口是80
    • HTTPS默认端口是443

Content-Length和Content-Type在请求中不一定存在(请求没有body(GET请求)情况下就不存在),像上面我抓的这个包就是GET请求,里面就没有这两个字段.它们俩是成对出现的,只要有其中一个,另一个必定存在.

  1. Content-Length: 当请求包含实体内容时,表示实体内容的字节大小,有助于服务器正确处理请求体。
  2. Content-Type: 描述请求主体的MIME类型,如 application/x-www-form-urlencoded 表示表单数据,multipart/form-data 用于文件上传。application/json 表示数据为 json 格式
  • User-Agent: 客户端的用户代理信息,包括浏览器类型、版本、操作系统等,帮助服务器提供定制化的响应或统计分析。
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0

分析图:

image-20240510144930879

  • Referer: 发起请求的页面地址,用于追踪用户是从哪个页面链接过来的。这个在HTTP请求头中可有可没有

  • Cookie: 发送给服务器的Cookie信息,用于维持用户会话状态或个性化设置,是浏览器本地数据存储的一种机制。

Cookie: BIDUPSID=DD7326D9CB3E780AE232E272F9988EF1; PSTM=1700320963; BAIDUID=CB65E88DF6D23B274067D86F39E33F91:FG=1; H_WISE_SIDS=40171_40369_40376_40398_40416_40305_40458_39662_40511_40512_60044_60026_60035_60048_60058; H_WISE_SIDS_BFESS=40171_40369_40376_40398_40416_40305_40458_39662_40511_40512_60044_60026_60035_60048_60058; BAIDUID_BFESS=CB65E88DF6D23B274067D86F39E33F91:FG=1; COOKIE_SESSION=130_0_8_3_5_14_1_1_8_6_1_3_56_0_0_0_1713166585_0_1713181572%7C9%23580281_10_1665372810%7C4; BAIDU_WISE_UID=wapp_1713714319309_20; H_PS_PSSID=40305_40080_60138_60186; BDUSS=2R5UzNPZzZ3ai1kNVlXcEZjVWc4ZnctT3ZVRmdGQllvOXpCb0JZNGljanFmMWxtRVFBQUFBJCQAAAAAAAAAAAEAAAA1MYH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOryMWbq8jFmc; BDUSS_BFESS=2R5UzNPZzZ3ai1kNVlXcEZjVWc4ZnctT3ZVRmdGQllvOXpCb0JZNGljanFmMWxtRVFBQUFBJCQAAAAAAAAAAAEAAAA1MYH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOryMWbq8jFmc; ZFY=DAt6xuFJrVO9Vof3C8Wq3xMauOxCp4CYAj4HYxdRdyg:C

我们也可以在浏览器中看到有哪些cookie数据

image-20240510145718964

请求报头有很多,还有其它的一些如下所示:

  1. Accept: 指定客户端能够接收的内容类型(MIME类型),例如 text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,表示优先接收HTML,然后是XML,最后是任何类型。
  2. Accept-Encoding: 客户端支持的内容编码方式,如gzip、deflate等,用于请求压缩内容以减少传输量。
  3. Accept-Language: 客户端期望接收的内容语言,如 en-US,en;q=0.5 表示首选英语(美国),其他英语也接受,但优先级较低。
  4. Authorization: 用于HTTP身份验证,包含用户的认证信息,如 Basic YWxhZGRpbjpvcGVuc2VzYW1lBearer your_token_here
  5. Cache-Control: 控制请求和响应的缓存机制,如 no-cache 表示不要使用缓存副本,必须从服务器重新获取。
  6. Connection: 指示对于当前事务完成后,是否关闭网络连接还是继续保持打开状态,如 keep-alive 表示持久连接。
  7. If-Modified-Since: 客户端缓存的资源最后修改时间,询问服务器资源是否有更新,用于条件请求。

6.HTTP响应

下图是刚才HTTP请求的响应报文

image-20240510151452242

内容如下:

HTTP/1.1 200 OK
Connection: keep-alive
Content-Encoding: gzip
Content-Security-Policy: frame-ancestors 'self' https://chat.baidu.com http://mirror-chat.baidu.com https://fj-chat.baidu.com https://hba-chat.baidu.com https://hbe-chat.baidu.com https://njjs-chat.baidu.com https://nj-chat.baidu.com https://hna-chat.baidu.com https://hnb-chat.baidu.com http://debug.baidu-int.com;
Content-Type: text/html; charset=utf-8
Date: Fri, 10 May 2024 07:14:05 GMT
Isprivate: 1
Server: BWS/1.1
Set-Cookie: H_PS_PSSID=40305_40080_60138_60237_60270_60275; path=/; expires=Sat, 10-May-25 07:14:05 GMT; domain=.baidu.com
Traceid: 1715325245044552423416257137435173222985
X-Ua-Compatible: IE=Edge,chrome=1
X-Xss-Protection: 1;mode=block
Transfer-Encoding: chunked

HTTP/1.1 200 OK:表示HTTP版本,状态码.

6.1 状态码

HTTP状态码是由三位数字组成的代码,服务器通过这些代码来告知客户端关于HTTP请求的状态。

  • 1xx (Informational - 信息性状态码): 这些状态码表示接收的请求正在处理,通常客户端不需要对它们做出进一步的动作。例如,100 Continue 表示客户端应继续其请求。
  • 2xx (Successful - 成功状态码): 表示请求已成功被服务器接收、理解,并接受了。最常见的状态码是 200 OK,表示请求已成功处理。
  • 3xx (Redirection - 重定向状态码): 表示需要客户端采取进一步的操作才能完成请求。例如,301 Moved Permanently 表示请求的资源已被永久移动到了新的URL。
  • 4xx (Client Error - 客户端错误状态码): 这类状态码指出客户端的请求有误,服务器无法处理。最熟知的例子是 404 Not Found,意味着请求的资源未找到。
  • 5xx (Server Error - 服务器错误状态码): 表示服务器在处理请求时发生错误。例如,500 Internal Server Error 指服务器遇到了未知错误,无法完成请求。

状态码有很多,熟悉常见的即可:

状态码含义
200 (OK)成功
301 永久重定向请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。
302 临时重定向与301类似。但资源只是临时被移动。客户端应继续使用原有URI
403 阻止访问客户端已知但没有访问权限
404 Not Found未找到请求的资源
405 方法不被允许不支持使用的请求方法,例如,表单需要使用 POST 但使用 GET 代替。
500 内部服务器错误服务器遇到某种问题、并且没有更好或更具体的错误代码
504 网关超时服务器处于请求中间状态。但是没有收到来自它路由到的服务器的及时响应

7.HTTP位于应用层(基于TCP)

HTTP(超文本传输协议)位于TCP/IP模型的应用层。这意味着它是建立在传输层协议之上,特别是基于TCP(传输控制协议)来实现数据的传输。TCP是一种面向连接的、可靠的传输协议,它保证了数据包的顺序传输和错误校验,确保数据的完整性。HTTP利用TCP提供的这些特性来确保从Web服务器到客户端(如浏览器)的请求和响应能够准确无误地传达。

当一个HTTP请求从客户端发出时,首先会通过TCP建立一个从客户端到服务器的连接(这通常涉及到TCP的三次握手过程)。接着,HTTP请求消息通过这个TCP连接发送到服务器,服务器处理请求后,再通过同一个TCP连接将HTTP响应消息返回给客户端。一旦数据交换完成,TCP连接可以被断开.

8.非持久和持久连接

HTTP协议中的非持久连接(Nonpersistent Connections)和持久连接(Persistent Connections)主要区别在于它们管理TCP连接的方式以及如何处理连续的请求和响应。

8.1 非持久连接

在HTTP的早期版本中,如HTTP/1.0,默认使用非持久连接。在这种模式下:

  • 每个HTTP请求/响应事务都使用一个新的TCP连接。
  • 服务器发送完响应后立即关闭TCP连接,不保留任何状态。
  • 如果客户端需要请求多个资源(如图片、CSS文件等),每一个都需要独立建立和关闭TCP连接,这导致了较高的延迟,因为每次连接都需要进行TCP的三次握手和四次挥手过程。
  • 这种方式增加了网络负担,因为每个连接都需要分配系统资源,且每次请求都包含了TCP连接的建立和拆除开销。

8.2 持久连接

随着HTTP协议的发展,特别是在HTTP/1.1中,持久连接成为了默认行为,显著提高了效率:

  • 一个TCP连接可以用于发送多个HTTP请求和接收多个响应,而不是每个请求都新建连接。
  • 服务器在发送完一个响应后,保持TCP连接的开启状态,允许同一个客户端发送额外的请求。
  • 这种模式减少了建立和关闭连接的开销,提高了整体性能,降低了延迟,特别是在请求多个资源的场景下更为明显。
  • 持久连接有两种形式:
    • 无流水线(Non-pipelined)持久连接:客户端需等待前一个请求的响应到达后,才能发送下一个请求。每个对象传输大约需要1个RTT(往返时间)。
    • 流水线(Pipelining)持久连接:理论上允许客户端在收到前一个响应之前发送多个请求,这样可以进一步减少延迟,但在实践中由于存在一些问题(如头部阻塞)并未广泛使用。

HTTP协议版本:

  • HTTP/1.0:较早的版本,每次请求响应都会建立新的TCP连接。
  • HTTP/1.1:引入了持久连接(Keep-Alive),提高了效率,支持管道化处理请求。
  • HTTP/2:进一步优化性能,支持多路复用、二进制分帧、头部压缩等特性。
  • HTTP/3:基于QUIC传输协议,改善了延迟和安全性,特别是在高延迟或不可靠的网络环境中。
评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

比奇堡的天没有云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值