HTTP 报文是在应用程序之间发送的数据块,这些数据块将通过以文本形式的元信息开头,用于 HTTP 协议交互。请求端(客户端)的 HTTP 报文叫做请求报文,响应端(服务器端)的叫做响应报文。 HTTP 报文本身是由多行(用 CR+LF 作换行符)数据构成的字符串文本。
HTTP 请求报文由请求行、请求头、空行和请求包体(body)组成。如下图所示:
真实示例:
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;
主要描述了客户端想要如何操作服务端的资源;请求行由三部分构成:
这三个部分通常使用空格(space)来分隔,最后要用 CRLF 换行表示结束。
GET / HTTP/1.1
这个请求行,结合之前的描述,意思就是“服务端妹子你好,我是客户端蛋蛋,现在我想获取网站根目录的默认信息,我这边用的协议版本是 1.1,麻烦你也要用这个版本回复我哦”
HTTP的报文头,报文头包含若干个属性,格式为“属性名:属性值”,服务端据此获取客户端的信息。与缓存相关的规则信息,均包含在header中,请求头可大致分为四种类型:通用首部字段、请求首部字段、响应首部字段、实体首部字段。这里先简单罗列,稍后做具体解释。
请求体就是 HTTP 要传输的内容,HTTP 可以承载很多类型的数字数据:图片、音频、视频、HTML 文档等。
HTTP 响应报文由状态行、响应头部、空行和响应包体(body)组成。如下图所示:
以请求 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
状态行包含了 协议版本、状态码以及状态描述。
和请求报文的请求头类似,响应头也由键值对组成,每行一对,键和值用英文冒号 : 分隔。响应头域允许服务器传递不能放在状态行的附加信息,这些域主要描述服务器的信息和Request-URI进一步的信息
服务器返回给浏览器的响应信息,响应数据的格式是根据服务器来的,常见的响应数据格式有:text/html、application/json等。
常见的响应格式:
在 HTTP 的请求头和响应头中都是由首部字段来表示的,首部内容可以为客户端和服务器分别处理请求和响应提供所需要的信息。
首部字段可以分为通用首部字段、请求首部字段、响应首部字段、实体首部字段。
通用首部字段是指请求报文和响应报文都会使用到的首部字段。
先来看下都有哪些字段:
通过指定 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: close
当服务器端想明确断开连接时,则指定 Connection 首部字段的值为 Close。
首部字段 Date 表明创建 HTTP 报文的日期和时间。
首部字段 Trailer 会事先说明在报文主体后记录了哪些首部字段。该首部字段可应用在 HTTP/1.1 版本分块传输编码时。
该字段规定了传输报文主体时采用的编码方式。 HTTP/1.1 的传输编码方式仅对分块传输编码有效。
请求首部字段是从客户端往服务器端发送请求报文中所使用的字段,用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容。
常用字段具体说明
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: iso-8859-5, unicode-1-1;q=0.8
通知服务器 客户端支持的字符集及字符集的相对优先顺序。
Accept-Encoding: gzip, deflate
首部字段用来告知服务器 客户端支持的内容编码及内容编码的优先级顺序。可一次性指定多种内容编码。
Accept-Language: zh-cn,zh;q=0.7,en-us,en;q=0.3
用来告知服务器 客户端能够处理的自然 语言集(指中文或英文等),以及自然语言集的相对优先级。可一次 指定多种自然语言集。
Authorization: Basic dWVub3NlbjpwYXNzd29yZA==
首部字段 Authorization 是用来告知服务器,客户端的认证信息(证书值)。
User-Agent: Mozilla/5.0 (windows NT 6.1; WOW64; rv:13.0)
首部字段 User-Agent 会将创建请求的浏览器和用户代理名称等信息传 达给服务器。
由网络爬虫发起请求时,有可能会在字段内添加爬虫作者的电子邮件地址。此外,如果请求经过代理,那么中间也很可能被添加上代理服务器的名称。
响应首部字段是由服务器端向客户端返回响应报文中所使用的字段,用于补充响应的附加信息、服务器信息,以及对客户端的附加要求等信息。
Accept-Ranges: bytes 当不能处理范围请求时,Accept-Ranges: none
用来告知客户端服务器是否能处理范围请 求,以指定获取服务器端某个部分的资源。
Age: 600
Age 能告知客户端,源服务器在多久前创建了响应。字段值的单位为秒。
Location: http://www.usagidesign.jp/sample.html
该字段可以将响应接收方引导至某个与请求 URI 位置 不同的资源。
基本上,该字段会配合 3xx :Redirection 的响应,提供重定向的 URI。
Retry-After: 120
告知客户端应该在多久之后再次发送请求。主要 配合状态码 503 Service Unavailable 响应,或 3xx Redirect 响应一起使 用。
Server: Apache/2.2.17 (Unix)
告知客户端当前服务器上安装的 HTTP 服务器应用程序的信息。
实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。
Allow: GET, HEAD
用于通知客户端能够支持 Request-URI 指定资源的所有 HTTP 方法。
Content-Encoding: gzip
会告知客户端服务器对实体的主体部分选用的内容编码方式。
Content-Language: zh-CN
首部字段 Content-Language 会告知客户端,实体主体使用的自然语言。
Content-Length: 15000
表明了实体主体部分的大小(单位是字 节)。
Content-Type: text/html; charset=UTF-8
说明了实体主体内对象的媒体类型。