HTTP首部字段完全解析

http协议是前端开发人员最常接触到的网络协议。在开发过程中,尤其是调试过程中避免不了需要去分析http请求的详细信息。在这其中头部字段提供的信息最多,比如通过响应状态码我们可以直观的看到响应的大致状态。那么你是否清楚http首部字段都有哪些,具体含义是什么,可选值又有哪些呢?看完下面的内容,我相信对于这几个问题你就会迎刃而解。

http协议用于交互的信息被称为HTTP报文。请求端(客户端)的HTTP报文叫做请求报文,响应端(服务器端)的HTTP报文叫做响应报文。HTTP报文大致可以分为报文首部和报文主题两部分。我们来看下请求报文和响应报文的结构。

从上图我们可以看出,请求报文和响应报文的首部内容由以下数据组成。

请求行

包含用于请求的方法,请求 URI 和 HTTP 版本。

状态行

包含表明响应结果的状态码,原因短语和 HTTP 版本。

首部字段

包含表示请求和响应的各种条件和属性的各类首部。

下面我们重点来看下首部字段的一些信息,并且对最常用到的首部字段的含义及可选值都有哪些,分别代表什么意思进行讲解。
http首部字段类型根据实际用途被分为以下4种类型:

通用首部字段(General Header Fields)

请求报文和响应报文两方都会使用的首部。

请求首部报文(Request Headers Fields)

从客户端向服务端发送请求报文时使用的首部。补充了请求的附加内容,客户端信息,响应内容相关优先级等信息。

响应首部字段(Response Header Fields)

从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。

实体首部字段(Entity Header Fields)

针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体相关的信息。


其中http/1.1规范定义了47种首部字段,下面我们按照以上的四个大类对这47种字段进行一个简要解释:

通用首部字段

首部字段名 说明
Cache-Control 控制缓存的行为
Connection 连接的管理
Date 创建报文的日期时间
Pragma 报文指令
Trailer 报文末端的首部一览
Transfer-Encoding 指定报文主体的传输编码方式
Upgrade 升级为其他协议
Via 代理服务器的相关信息
Warning 错误通知

请求首部字段

首部字段名 说明
Accept 用户代理可处理的媒体类型
Accept-Charset 优先的字符集
Accept-Encoding 优先的内容编码
Accept-Language 优先的语言(自然语言)
Authorization Web认证信息
Expect 期待服务器的特定行为
From 用户的电子邮箱地址
Host 请求资源所在服务器
If-Match 比较实体标记(ETag)
If-Modified-Since 比较资源的更新时间
If-None-Match 比较实体标记(与 If-Match 相反)
If-Range 资源未更新时发送实体 Byte 的范围请求
If-Unmodified-Since 比较资源的更新时间(与If-Modified-Since相反)
Max-Forwards 最大传输逐跳数
Proxy-Authorization 代理服务器要求客户端的认证信息
Range 实体的字节范围请求
Referer 对请求中URI的原始获取方
TE 传输编码的优先级
User-Agent HTTP客户端程序的信息

响应首部字段

首部字段名 说明
Accept-Ranges 是否接受字节范围请求
Age 推算资源创建经过时间
ETag 资源的匹配信息
Location 令客户端重定向至指定URI
Proxy-Authenticate 代理服务器对客户端的认证信息
Retry-After 对再次发起请求的时机要求
Server HTTP服务器的安装信息
Vary 代理服务器缓存的管理信息
WWW-Authenticate 服务器对客户端的认证信息

实体首部字段

首部字段名 说明
Allow 资源可支持的HTTP方法
Content-Encoding 实体主体适用的编码方式
Content-Language 实体主体的自然语言
Content-Length 实体主体的大小(单位:字节)
Content-Location 替代对应资源的URI
Content-MD5 实体主体的报文摘要
Content-Range 实体主体的位置范围
Content-Type 实体主体的媒体类型
Expires 实体主体过期的日期时间
Last-Modified 资源的最后修改日期时间

常用首部字段分析:

1. Cache-Control 指令一览

可用的指令按请求和响应分类如下所示:

缓存请求指令:

指令 参数 说明
no-cache 强制向原服务器再次验证
no-store 不缓存请求或响应的任何内容
max-age = [ 秒] 必须 响应的最大Age值
max-stale( = [ 秒]) 可省略 接收已过期的响应
min-fresh = [ 秒] 必需 期望在指定的时间内的响应仍有效
no-transform 代理不可更改媒体类型
only-if-cached 代理不可更改媒体类型
cache-extension - 新指令标记(token)

缓存响应指令:

指令 参数 说明
public 可向任意方提供响应的缓存
private 可省略 仅向特定用户返回响应
no-cache 可省略 缓存前必需先确认其有效性
no-store 不缓存请求或响应的任何内容
no-transform 代理不可更改媒体类型
must-revalidate 可缓存但必须再向源服务器进行确认
proxy-revalidate 要求中间缓存服务器对缓存的响应有效性再进行确认
max-age=[秒] 必需 响应的最大Age值
s-maxage=[秒] 必需 公共缓存服务器响应的最大Age值
cache-extension - 新指令标记(token)

从字面意思上很容易把 no-cache 误解成为不缓存,但事实上 no-cache 代表不缓
存过期的资源,缓存会向源服务器进行有效期确认后处理资源,也许称为 do-notserve-
from-cache-without-revalidation 更合适。no-store 才是真正地不进行缓存,请
读者注意区别理解

2. Connection

Connection首部字段具备如下两个作用

  1. 控制不再转发给代理的首部字段
  2. 管理持久连接

HTTP/1.1 版本的默认连接都是持久连接。为此,客户端会在持
久连接上连续发送请求。当服务器端想明确断开连接时,则指定
Connection 首部字段的值为 Close。

Date

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

3. Pragma

Pragma是HTTP/1.1之前版本的历史遗留字段,仅作为与HTTP/1.0的向后兼容而定义。

规范定义的形式唯一,如下所示:

Pragma: no-cache

该首部字段属于通用首部字段,但只用在客户端发送的请求中。客户端会要求所有的中间服务器不返回缓存的资源。

所有的中间服务器如果都能以 HTTP/1.1 为基准,那直接采用 Cache-
Control: no-cache 指定缓存的处理方式是最为理想的。但要整体掌握
全部中间服务器使用的 HTTP 协议版本却是不现实的。因此,发送的
请求会同时含有下面两个首部字段。

Cache-Control: no-cache
Pragma: no-cache

4. Upgrade

首部字段 Upgrade 用于检测 HTTP 协议及其他协议是否可使用更高的
版本进行通信,其参数值可以用来指定一个完全不同的通信协议。

Upgrade

使用首部字段 Upgrade 时,还需要额外指定Connection:Upgrade。

5. Accept

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3

Accept 首部字段可通知服务器,用户代理能够处理的媒体类型及媒体
类型的相对优先级。可使用 type/subtype 这种形式,一次指定多种媒
体类型。

6. Accept-Charset

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

Accept-Charset 首部字段可用来通知服务器用户代理支持的字符集及
字符集的相对优先顺序。另外,可一次性指定多种字符集。与首部字
段 Accept 相同的是可用权重 q 值来表示相对优先级

7. Accept-Encoding

Accept-Encoding: gzip, deflate

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

下面试举出几个内容编码的例子。

  • gzip

由文件压缩程序 gzip(GNU zip)生成的编码格式
(RFC1952),采用 Lempel-Ziv 算法(LZ77)及 32 位循环冗余
校验(Cyclic Redundancy Check,通称 CRC)。

  • compress

    由 UNIX 文件压缩程序 compress 生成的编码格式,采用 Lempel-
    Ziv-Welch 算法(LZW)。

  • deflate

    组合使用 zlib 格式(RFC1950)及由 deflate 压缩算法
    (RFC1951)生成的编码格式。

  • identity

    不执行压缩或不会变化的默认编码格式

采用权重 q 值来表示相对优先级,这点与首部字段 Accept 相同。另
外,也可使用星号(*)作为通配符,指定任意的编码格式。

8. Accept-Language

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

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

和 Accept 首部字段一样,按权重值 q 来表示相对优先级。在上述图
例中,客户端在服务器有中文版资源的情况下,会请求其返回中文版
对应的响应,没有中文版时,则请求返回英文版响应。

9. If-Match

形如 If-xxx 这种样式的请求首部字段,都可称为条件请求。服务器接
收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。

首部字段 If-Match,属附带条件之一,它会告知服务器匹配资源所用
的实体标记(ETag)值。这时的服务器无法使用弱 ETag 值。(请参
照本章有关首部字段 ETag 的说明)

服务器会比对 If-Match 的字段值和资源的 ETag 值,仅当两者一致
时,才会执行请求。反之,则返回状态码 412 Precondition Failed 的响
应。

还可以使用星号(*)指定 If-Match 的字段值。针对这种情况,服务
器将会忽略 ETag 的值,只要资源存在就处理请求。

10. Referer

Referer: http://172.30.1.34:4200/

首部字段 Referer 会告知服务器请求的原始资源的 URI。

11. User-Agent

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36

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

12. Age

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

若创建该响应的服务器是缓存服务器,Age 值是指缓存后的响应再次
发起认证到认证完成的时间值。代理创建响应时必须加上首部字段
Age。

13. ETag

首部字段 ETag 能告知客户端实体标识。它是一种可将资源以字符串
形式做唯一性标识的方式。服务器会为每份资源分配对应的 ETag
值。

14. Location

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

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

几乎所有的浏览器在接收到包含首部字段 Location 的响应后,都会强
制性地尝试对已提示的重定向资源的访问。

15. Content-Encoding

首部字段 Content-Encoding 会告知客户端服务器对实体的主体部分选
用的内容编码方式。内容编码是指在不丢失实体信息的前提下所进行
的压缩。

16. Content-Language

Content-Language: zh-CN

首部字段 Content-Language 会告知客户端,实体主体使用的自然语言
(指中文或英文等语言)。

17. Content-Length

Content-Length: 15000

首部字段 Content-Length 表明了实体主体部分的大小(单位是字
节)。对实体主体进行内容编码传输时,不能再使用 Content-Length
首部字段

18. Content-Type

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

首部字段 Content-Type 说明了实体主体内对象的媒体类型。和首部字
段 Accept 一样,字段值用 type/subtype 形式赋值。

19. Last-Modified

Last-Modified: Wed, 21 Aug 2019 06:18:22 GMT

首部字段 Last-Modified 指明资源最终修改的时间。一般来说,这个
值就是 Request-URI 指定资源被修改的时间。但类似使用 CGI 脚本进
行动态数据处理时,该值有可能会变成数据最终修改时的时间。

Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31

服务器设置客户端cookie信息,以便管理客户端状态。

  • HttpOnly 属性

    Cookie 的 HttpOnly 属性是 Cookie 的扩展功能,它使 JavaScript 脚本
    无法获得 Cookie。其主要目的为防止跨站脚本攻击(Cross-site
    scripting,XSS)对 Cookie 的信息窃取。

发送指定 HttpOnly 属性的 Cookie 的方法如下所示。

Set-Cookie: name=value; HttpOnly

通过上述设置,通常从 Web 页面内还可以对 Cookie 进行读取操作。
但使用 JavaScript 的 document.cookie 就无法读取附加 HttpOnly 属性后
的 Cookie 的内容了。因此,也就无法在 XSS 中利用 JavaScript 劫持
Cookie 了。

以上所列出的首部字段都是基于HTTP/1.1,到这里本文要介绍的相关知识也就结束了。对于文章开头提出的三个问题不知道你现在有没有清楚呢。最后希望小伙伴可以在下方留言评论(对于文章的文字排版,写作技巧,相关内容都可以相互交流学习)

posted @ 2019-09-03 14:35 寻找石头鱼 阅读(...) 评论(...) 编辑 收藏