HTTP 报文详解

419 阅读9分钟

大家好,我是蛋蛋。 HTTP 报文是在应用程序之间发送的数据块,这些数据块将通过以文本形式的元信息开头,用于 HTTP 协议交互。请求端(客户端)的 HTTP 报文叫做请求报文,响应端(服务器端)的叫做响应报文。 HTTP 报文本身是由多行(用 CR+LF 作换行符)数据构成的字符串文本。

请求报文

HTTP 请求报文由请求行请求头空行请求包体(body)组成。如下图所示:

image-20211224161037961

真实示例:

GET / HTTP/1.1     
Host: www.baidu.com
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
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.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: BIDUPSID=8B0207CE0B6364E5934651E84F17999B; PSTM=1619707475; 

1.请求行

主要描述了客户端想要如何操作服务端的资源;请求行由三部分构成:

  • 请求方法:表示对资源期望进行何种操作,常用的如 GET、POST
  • 请求目标:通常是一个 URL ,表明了要操作的资源。
  • 版本号:表示报文使用的 HTTP 协议版本。

这三个部分通常使用空格(space)来分隔,最后要用 CRLF 换行表示结束。

GET / HTTP/1.1  

这个请求行,结合之前的描述,意思就是“服务端妹子你好,我是客户端蛋蛋,现在我想获取网站根目录的默认信息,我这边用的协议版本是 1.1,麻烦你也要用这个版本回复我哦”

2.请求头

HTTP的报文头,报文头包含若干个属性,格式为“属性名:属性值”,服务端据此获取客户端的信息。与缓存相关的规则信息,均包含在header中,请求头可大致分为四种类型:通用首部字段、请求首部字段、响应首部字段、实体首部字段。这里先简单罗列,稍后做具体解释。

3.请求体

请求体就是 HTTP 要传输的内容,HTTP 可以承载很多类型的数字数据:图片、音频、视频、HTML 文档等。

  • 介绍响应报文
  • 首部字段
  • 介绍功能

响应报文

HTTP 响应报文由状态行响应头部空行响应包体(body)组成。如下图所示:

image-20211224161004923

以请求 www.baidu.com为例:

HTTP/1.1 200 OK
Bdpagetype: 1
Bdqid: 0xfb0d743100040ad2
Cache-Control: private
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html;charset=utf-8
Date: Fri, 24 Dec 2021 08:20:44 GMT
Expires: Fri, 24 Dec 2021 08:20:44 GMT
Server: BWS/1.1
Set-Cookie: BDSVRTM=17; path=/
Set-Cookie: BD_HOME=1; path=/
Set-Cookie: H_PS_PSSID=35635_34439_35104_35628_35488_35436_35456_34584_35491_35584_35586_34873_35317_26350_35610_35562; path=/; domain=.baidu.com
Strict-Transport-Security: max-age=172800
Traceid: 1640334044050133761018090243032019634898
X-Frame-Options: sameorigin
X-Ua-Compatible: IE=Edge,chrome=1
Transfer-Encoding: chunked

1.状态行

状态行包含了 协议版本状态码以及状态描述

  • 协议版本:指明了报文使用的 HTTP 协议版本

  • 状态码:状态码是一个三位数字,用来表示处理的结果,下面列出了状态码的类别:

    image-20211225153118066

  • 状态描述:这个是作为状态码的补充,是一段更详细的文字,帮助人们理解原因。

2.响应头部

和请求报文的请求头类似,响应头也由键值对组成,每行一对,键和值用英文冒号 : 分隔。响应头域允许服务器传递不能放在状态行的附加信息,这些域主要描述服务器的信息和Request-URI进一步的信息

3.响应包体

服务器返回给浏览器的响应信息,响应数据的格式是根据服务器来的,常见的响应数据格式有:text/html、application/json等。

常见的响应格式:

image-20211225160245699

HTTP 首部字段

在 HTTP 的请求头和响应头中都是由首部字段来表示的,首部内容可以为客户端和服务器分别处理请求和响应提供所需要的信息。

首部字段可以分为通用首部字段请求首部字段响应首部字段实体首部字段

通用首部字段

通用首部字段是指请求报文和响应报文都会使用到的首部字段。

先来看下都有哪些字段:

image-20211225164859328

Cache-Control

通过指定 Cache-Control 的指令,就能操作缓存的工作机制。

一般在客户端和服务端之间还存在一个缓存服务器,如果请求的资源在缓存服务器中有,就不会再请求源服务器,提高了请求响应的效率。

指令的参数可以多选,通过“,”分隔。

Cache-Control: private, max-age=0, no-cache

public 指令

Cache-Control: public

当使用 public 指令时,明确表明其他用户也可以利用缓存。

private 指令

Cache-Control: private

当指定 private 指令后,响应只以特定的用户作为对象,这与 public 指令的行为相反。

缓存服务器会对该特定用户提供资源缓存的服务,对于其他用户发送过来的请求,代理服务器则不会返回缓存。

no-cache 指令

Cache-Control: no-cache

使用 no-cache 指令可以防止从缓存中拿过期的数据。

在请求中如果包含该指令,则客户端将不会接收缓存过的响应,中间的缓存服务器会把请求转发给源服务器。

如果响应中包含该指令,缓存服务器会向源服务器进行资源有效期的确认,如果是过期的资源则不缓存。

no-store 指令

Cache-Control: no-store

该指令规定缓存不能在本地存储请求或响应的任一部分。这里我们要和上面那个 no-cache 指令要区分开,no-store才是真正不进行缓存,no-cache 只是不对过期的资源进行缓存。

Connection

Connection 有两个作用:控制不再转发给代理的首部字段、管理持久连接。

  • 控制不再转发给代理的首部字段

    Connection: 不再转发的首部字段名
    
  • 管理持久连接
Connection: close

当服务器端想明确断开连接时,则指定 Connection 首部字段的值为 Close。

Date

首部字段 Date 表明创建 HTTP 报文的日期和时间。

Trailer

首部字段 Trailer 会事先说明在报文主体后记录了哪些首部字段。该首部字段可应用在 HTTP/1.1 版本分块传输编码时。

Transfer-Encoding

该字段规定了传输报文主体时采用的编码方式。 HTTP/1.1 的传输编码方式仅对分块传输编码有效。

请求首部字段

请求首部字段是从客户端往服务器端发送请求报文中所使用的字段,用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容。

image-20211225182959508

常用字段具体说明

Accept

Accept: text/html,application/xhtml+xml,application/xml;q=0.3

该字段可以通知服务器 客户端能够接收处理的媒体类型及优先级。

比如,如果浏览器不支持 PNG 图片的显示,那 Accept 就不指定 image/png ,而指定可处理的 image/gif 和 image/jpeg 等图片类型。 若想要给显示的媒体类型增加优先级,则使用 q= 来额外表示权重值。用分号(;)进行分隔。权重值 q 的范围是 0~1(可精确到小数点 后 3 位),且 1 为最大值。不指定权重 q 值时,默认权重为 q=1.0。

Accept-Charset

Accept-Charset: iso-8859-5, unicode-1-1;q=0.8

通知服务器 客户端支持的字符集及字符集的相对优先顺序。

Accept-Encoding

Accept-Encoding: gzip, deflate

首部字段用来告知服务器 客户端支持的内容编码及内容编码的优先级顺序。可一次性指定多种内容编码。

Accept-Language

Accept-Language: zh-cn,zh;q=0.7,en-us,en;q=0.3

用来告知服务器 客户端能够处理的自然 语言集(指中文或英文等),以及自然语言集的相对优先级。可一次 指定多种自然语言集。

Authorization

Authorization: Basic dWVub3NlbjpwYXNzd29yZA==

首部字段 Authorization 是用来告知服务器,客户端的认证信息(证书值)。

User-Agent

User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0)

首部字段 User-Agent 会将创建请求的浏览器和用户代理名称等信息传 达给服务器。

由网络爬虫发起请求时,有可能会在字段内添加爬虫作者的电子邮件地址。此外,如果请求经过代理,那么中间也很可能被添加上代理服务器的名称。

响应首部字段

响应首部字段是由服务器端向客户端返回响应报文中所使用的字段,用于补充响应的附加信息、服务器信息,以及对客户端的附加要求等信息。
image-20211225190148813

Accept-Ranges

Accept-Ranges: bytes    当不能处理范围请求时,Accept-Ranges: none

用来告知客户端服务器是否能处理范围请 求,以指定获取服务器端某个部分的资源。

Age

Age: 600

Age 能告知客户端,源服务器在多久前创建了响应。字段值的单位为秒。

Location

Location: http://www.usagidesign.jp/sample.html

该字段可以将响应接收方引导至某个与请求 URI 位置 不同的资源。

基本上,该字段会配合 3xx :Redirection 的响应,提供重定向的 URI。

Retry-After

Retry-After: 120

告知客户端应该在多久之后再次发送请求。主要 配合状态码 503 Service Unavailable 响应,或 3xx Redirect 响应一起使 用。

Server

Server: Apache/2.2.17 (Unix)

告知客户端当前服务器上安装的 HTTP 服务器应用程序的信息。

实体首部字段

实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。

image-20211225191750448

Allow

Allow: GET, HEAD

用于通知客户端能够支持 Request-URI 指定资源的所有 HTTP 方法。

Content-Encoding

Content-Encoding: gzip

会告知客户端服务器对实体的主体部分选用的内容编码方式。

Content-Language

Content-Language: zh-CN

首部字段 Content-Language 会告知客户端,实体主体使用的自然语言。

Content-Length

Content-Length: 15000

表明了实体主体部分的大小(单位是字 节)。

Content-Type

Content-Type: text/html; charset=UTF-8

说明了实体主体内对象的媒体类型。