title: HTTP协议详解(二)
date: 2018-05-18 18:16:47
tags:
HTTP头部全罗列
HTTP报文结构
HTTP请求报文
在请求中,HTTP报文由请求方法、URI、HTTP版本、HTTP首部字段等部分构成。
GET / HTTP/1.1 Host: www.baidu.com Connection: keep-alive Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Cookie: BAIDUID=9D8BBF109C54257FDF493BEFB21C48C0:FG=1; BIDUPSID=9D8BBF109C54257FDF493BEFB21C48C0; PSTM=1517121373; BD_LAST_QID=10303242358279539047
image.png
响应报文
响应报文由HTTP版本、状态码(数字和原因短语)、HTTP首部等字段组成。
HTTP/1.1 200 OK Bdpagetype: 1Bdqid: 0xa3f1718e00024488Cache-Control: privateConnection: Keep-Alive Content-Encoding: gzip Content-Type: text/html Cxy_all: baidu+a099bc6c5584759c3f26c3fae21e11fb Date: Sun, 27 May 2018 09:57:02 GMT Expires: Sun, 27 May 2018 09:56:48 GMT Server: BWS/1.1Set-Cookie: BDSVRTM=0; path=/ Set-Cookie: BD_HOME=0; path=/ Set-Cookie: H_PS_PSSID=1431_21107_26350_20927; path=/; domain=.baidu.com Strict-Transport-Security: max-age=172800Vary: Accept-Encoding X-Ua-Compatible: IE=Edge,chrome=1Transfer-Encoding: chunked
image.png
HTTP首部字段
HTTP首部字段结构
HTTP首部字段是由首部字段名和字段值组成,中间用英文分号分隔。
首部字段名: 字段值
另外,字段值对应单个HTTP首部字段可以有多个值,用英文逗号隔开。
Keep-Alive: timeout=15, max=100
若 HTTP 首部字段重复了会如何?
当 HTTP 报文首部中出现了两个或两个以上具有相同首部字段名时
会怎么样?这种情况在规范内尚未明确,根据浏览器内部处理逻辑
的不同,结果可能并不一致。有些浏览器会优先处理第一次出现的
首部字段,而有些则会优先处理最后出现的首部字段。
End-to-end 首部和 Hop-by-hop 首部
HTTP 首部字段将定义成缓存代理和非缓存代理的行为,分成 2 种类型。
端到端首部(End-to-end Header)
分在此类别中的首部会转发给请求 / 响应对应的最终接收目标,且必 须保存在由缓存生成的响应中,另外规定它必须被转发。
逐跳首部(Hop-by-hop Header)
分在此类别中的首部只对单次转发有效,会因通过缓存或代理而不再 转发。HTTP/1.1 和之后版本中,如果要使用 hop-by-hop 首部,需提 供 Connection 首部字段。
下面列举了 HTTP/1.1 中的逐跳首部字段。除这 8 个首部字段之外, 其他所有字段都属于端到端首部。
Connection
Keep-Alive
Proxy-Authenticate
Proxy-Authorization
Trailer
TE
Transfer-Encoding
Upgrade
HTTP首部字段一览
HTTP/1.1 规范定义了如下 47 种首部字段。
HTTP通用首部字段(General Header Fields)
请求报文和响应报文两方都会使用的首部。
首部字段名 | 说明 |
---|---|
Cache-Control | 控制缓存行为 |
Connection | 逐跳首部、连接的管理 |
Date | 创建豹纹的日期时间 |
Pragma | 报文指令 |
Trailer | 报文末端的首部一览 |
Transfer-Encoding | 指定报文主体的传输编码方式 |
Upgrade | 升级为其他协议 |
Via | 代理服务器的相关信息 |
Warning | 错误通知 |
Cache-Control
控制缓存的指令,详见HTTP缓存技术详解
Connection
Connection首部字段具备如下两个作用。
控制不再转发给代理的首部字段
Connection: 不再转发的首部字段名
在客户端发送请求和服务器返回响应内,使用 Connection 首部字 段,可控制不再转发给代理的首部字段(即 Hop-by-hop 首 部)。
管理持久连接
Connection: close
HTTP/1.1 版本的默认连接都是持久连接。为此,客户端会在持 久连接上连续发送请求。当服务器端想明确断开连接时,则指定 Connection 首部字段的值为 Close。
Connection: Keep-Alive
HTTP/1.1 之前的 HTTP 版本的默认连接都是非持久连接。为 此,如果想在旧版本的 HTTP 协议上维持持续连接,则需要指定 Connection 首部字段的值为 Keep-Alive。为了兼容HTTP/1.1之前的版本,因此一般都会在请求的时候加上这个字段。
Date
首部字段 Date 表明创建 HTTP 报文的日期和时间。
HTTP/1.1 协议使用在 RFC1123 中规定的日期时间的格式,如下 示 例。
Date: Tue, 03 Jul 2012 04:40:59 GMT
Pragma
Pragma 是 HTTP/1.1 之前版本的历史遗留字段,仅作为与 HTTP/1.0 的向后兼容而定义。
规范定义的形式唯一,如下所示。
Pragma: no-cache
该首部字段属于通用首部字段,但只用在客户端发送的请求中。客户 端会要求所有的中间服务器不返回缓存的资源。
所有的中间服务器如果都能以 HTTP/1.1 为基准,那直接采用 CacheControl: no-cache 指定缓存的处理方式是最为理想的。但要整体掌握 全部中间服务器使用的 HTTP 协议版本却是不现实的。因此,发送的 请求会同时含有下面两个首部字段。
Cache-Control: no-cache Pragma: no-cache
Trailer
首部字段 Trailer 会事先说明在报文主体后记录了哪些首部字段。该 首部字段可应用在 HTTP/1.1 版本分块传输编码时。
HTTP/1.1 200 OK Date: Tue, 03 Jul 2012 04:40:56 GMT Content-Type: text/html ... Transfer-Encoding: chunked Trailer: Expires ...(报文主体)... 0 Expires: Tue, 28 Sep 2004 23:59:59 GMT
以上用例中,指定首部字段 Trailer 的值为 Expires,在报文主体之后 (分块长度 0 之后)出现了首部字段 Expires。
Transfer-Encoding
首部字段 Transfer-Encoding 规定了传输报文主体时采用的编码方式。 HTTP/1.1 的传输编码方式仅对分块传输编码有效。
HTTP/1.1 200 OK Date: Tue, 03 Jul 2012 04:40:56 GMT Cache-Control: public, max-age=604800Content-Type: text/javascript; charset=utf-8Expires: Tue, 10 Jul 2012 04:40:56 GMT X-Frame-Options: DENY X-XSS-Protection: 1; mode=block Content-Encoding: gzip Transfer-Encoding: chunked Connection: keep-alive cf0 16进制(10进制为3312) ...3312字节分块数据...392 16进制(10进制为914) ...914字节分块数据...0
以上用例中,正如在首部字段 Transfer-Encoding 中指定的那样,有效 使用分块传输编码,且分别被分成 3312 字节和 914 字节大小的分块 数据。
image.png
上图用例中,首部字段 Upgrade 指定的值为 TLS/1.0。请注意此处两 个字段首部字段的对应关系,Connection 的值被指定为 Upgrade。 Upgrade 首部字段产生作用的 Upgrade 对象仅限于客户端和邻接服务 器之间。因此,使用首部字段 Upgrade 时,还需要额外指定 Connection:Upgrade。
对于附有首部字段 Upgrade 的请求,服务器可用 101 Switching Protocols 状态码作为响应返回。
Via
使用首部字段 Via 是为了追踪客户端与服务器之间的请求和响应报文 的传输路径。
报文经过代理或网关时,会先在首部字段 Via 中附加该服务器的信 息,然后再进行转发。这个做法和 traceroute 及电子邮件的 Received 首部的工作机制很类似。
首部字段 Via 不仅用于追踪报文的转发,还可避免请求回环的发生。 所以必须在经过代理时附加该首部字段内容。
Via 首部是为了追踪传输路径,所以经常会和 TRACE 方法一起使 用。比如,代理服务器接收到由 TRACE 方法发送过来的请求(其中 Max-Forwards: 0)时,代理服务器就不能再转发该请求了。这种情况 下,代理服务器会将自身的信息附加到 Via 首部后,返回该请求的响 应。
Warning
HTTP/1.1 的 Warning 首部是从 HTTP/1.0 的响应首部(Retry-After)演 变过来的。该首部通常会告知用户一些与缓存相关的问题的警告。
Warning 首部的格式如下。最后的日期时间部分可省略。
Warning: [警告码][警告的主机:端口号]“[警告内容]”([日期时间])
请求首部字段
请求首部字段是从客户端往服务器端发送请求报文中所使用的字段, 用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等 内容。
Accept
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.1
Accept 首部字段可通知服务器,用户代理能够处理的媒体类型及媒体 类型的相对优先级。可使用 type/subtype 这种形式,一次指定多种媒 体类型。
Accept-Charset
Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
Accept-Charset 首部字段可用来通知服务器用户代理支持的字符集及 字符集的相对优先顺序。另外,可一次性指定多种字符集。与首部字 段 Accept 相同的是可用权重 q 值来表示相对优先级。 该首部字段应用于内容协商机制的服务器驱动协商。
Accept-Encodeing
Accept-Encoding: gzip, deflate
Accept-Encoding 首部字段用来告知服务器用户代理支持的内容编码及 内容编码的优先级顺序。可一次性指定多种内容编码。
下面是常见的几种编码:
gzip
由文件压缩程序 gzip(GNU zip)生成的编码格式 (RFC1952),采用 Lempel-Ziv 算法(LZ77)及 32 位循环冗余 校验(Cyclic Redundancy Check,通称 CRC)。
compress
由 UNIX 文件压缩程序 compress 生成的编码格式,采用 LempelZiv-Welch 算法(LZW)。
deflate
组合使用 zlib 格式(RFC1950)及由 deflate 压缩算法 (RFC1951)生成的编码格式。
identity
不执行压缩或不会变化的默认编码格式
采用权重 q 值来表示相对优先级,这点与首部字段 Accept 相同。另 外,也可使用星号(*)作为通配符,指定任意的编码格式。
Accept-Language
Accept-Language: zh-cn,zh;q=0.7,en-us,en;q=0.3
首部字段 Accept-Language 用来告知服务器用户代理能够处理的自然 语言集(指中文或英文等),以及自然语言集的相对优先级。可一次 指定多种自然语言集。 和 Accept 首部字段一样,按权重值 q 来表示相对优先级。
在上述示例中,客户端在服务器有中文版资源的情况下,会请求其返回中文版 对应的响应,没有中文版时,则请求返回英文版响应。
Authorization
Authorization: Basic dWVub3NlbjpwYXNzd29yZA==
首部字段 Authorization 是用来告知服务器,用户代理的认证信息(证 书值)。通常,想要通过服务器认证的用户代理会在接收到返回的 401 状态码响应后,把首部字段 Authorization 加入请求中。共用缓存 在接收到含有 Authorization 首部字段的请求时的操作处理会略有差 异。
Host
Host: www.baidu.com:80
首部字段 Host 会告知服务器,请求的资源所处的互联网主机名和端 口号。Host 首部字段在 HTTP/1.1 规范内是唯一一个必须被包含在请 求内的首部字段。
首部字段 Host 和以单台服务器分配多个域名的虚拟主机的工作机制 有很密切的关联,这是首部字段 Host 必须存在的意义。
请求被发送至服务器时,请求中的主机名会用 IP 地址直接替换解 决。但如果这时,相同的 IP 地址下部署运行着多个域名,那么服务 器就会无法理解究竟是哪个域名对应的请求。因此,就需要使用首部 字段 Host 来明确指出请求的主机名。若服务器未设定主机名,那直 接发送一个空值即可。
If-Match
If-Match: "123456"
形如 If-xxx 这种样式的请求首部字段,都可称为条件请求。服务器接 收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。
首部字段 If-Match,属附带条件之一,它会告知服务器匹配资源所用 的实体标记(ETag)值。这时的服务器无法使用弱 ETag 值。
服务器会比对 If-Match 的字段值和资源的 ETag 值,仅当两者一致 时,才会执行请求。反之,则返回状态码 412 Precondition Failed 的响 应。
还可以使用星号(*)指定 If-Match 的字段值。针对这种情况,服务 器将会忽略 ETag 的值,只要资源存在就处理请求。
这是一个缓存字段,具体缓存机制可以参考HTTP缓存技术详解
If-Modified-Since
If-Modified-Since: Thu, 15 Apr 2004 00:00:00 GMT
首部字段 If-Modified-Since,属附带条件之一,它会告知服务器若 IfModified-Since 字段值早于资源的更新时间,则希望能处理该请求。 而在指定 If-Modified-Since 字段值的日期时间之后,如果请求的资源 都没有过更新,则返回状态码 304 Not Modified 的响应。
If-Modified-Since 用于确认代理或客户端拥有的本地资源的有效性。 获取资源的更新日期时间,可通过确认首部字段 Last-Modified 来确 定。
If-None-Match
If-None-Match: "123456"
首部字段 If-None-Match 属于附带条件之一。它和首部字段 If-Match 作用相反。用于指定 If-None-Match 字段值的实体标记(ETag)值与 请求资源的 ETag 不一致时,它就告知服务器处理该请求。 在 GET 或 HEAD 方法中使用首部字段 If-None-Match 可获取最新的资 源。因此,这与使用首部字段 If-Modified-Since 时有些类似。
If-Unmodified-Since
If-Unmodified-Since: Thu, 03 Jul 2012 00:00:00 GMT
首部字段 If-Unmodified-Since 和首部字段 If-Modified-Since 的作用相 反。它的作用的是告知服务器,指定的请求资源只有在字段值内指定 的日期时间之后,未发生更新的情况下,才能处理请求。如果在指定 日期时间后发生了更新,则以状态码 412 Precondition Failed 作为响应 返回。
Referer
Referer: http://www.hackr.jp/index.htm
首部字段 Referer 会告知服务器请求的原始资源的 URI。
客户端一般都会发送 Referer 首部字段给服务器。但当直接在浏览器 的地址栏输入 URI,或出于安全性的考虑时,也可以不发送该首部字 段。
因为原始资源的 URI 中的查询字符串可能含有 ID 和密码等保密信 息,要是写进 Referer 转发给其他服务器,则有可能导致保密信息的 泄露。
另外,Referer 的正确的拼写应该是 Referrer,但不知为何,大家一直 沿用这个错误的拼写。
User-Agent
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.117 Safari/537.36
首部字段 User-Agent 会将创建请求的浏览器和用户代理名称等信息传 达给服务器。
由网络爬虫发起请求时,有可能会在字段内添加爬虫作者的电子邮件 地址。此外,如果请求经过代理,那么中间也很可能被添加上代理服 务器的名称。
响应首部字段
响应首部字段是由服务器端向客户端返回响应报文中所使用的字段, 用于补充响应的附加信息、服务器信息,以及对客户端的附加要求等 信息。
Age
Age: 600
首部字段 Age 能告知客户端,源服务器在多久前创建了响应。字段值 的单位为秒。
若创建该响应的服务器是缓存服务器,Age 值是指缓存后的响应再次 发起认证到认证完成的时间值。代理创建响应时必须加上首部字段 Age。
Etag
ETag: "82e22293907ce725faf67773957acd12"
首部字段 ETag 能告知客户端实体标识。它是一种可将资源以字符串 形式做唯一性标识的方式。服务器会为每份资源分配对应的 ETag 值。
另外,当资源更新时,ETag 值也需要更新。生成 ETag 值时,并没有 统一的算法规则,而仅仅是由服务器来分配。
这是一个缓存字段,具体缓存机制可以参考HTTP缓存技术详解
Location
Location: http://www.baidu.com/sample.html
使用首部字段 Location 可以将响应接收方引导至某个与请求 URI 位置 不同的资源。
基本上,该字段会配合 3xx :Redirection 的响应,提供重定向的 URI。
几乎所有的浏览器在接收到包含首部字段 Location 的响应后,都会强 制性地尝试对已提示的重定向资源的访问。
Retry-After
Retry-After: 120
首部字段 Retry-After 告知客户端应该在多久之后再次发送请求。主要 配合状态码 503 Service Unavailable 响应,或 3xx Redirect 响应一起使 用。
字段值可以指定为具体的日期时间(Wed, 04 Jul 2012 06:34:24 GMT 等格式),也可以是创建响应后的秒数。
Server
Server: Apache/2.2.6 (Unix) PHP/5.2.5
首部字段 Server 告知客户端当前服务器上安装的 HTTP 服务器应用程 序的信息。不单单会标出服务器上的软件应用名称,还有可能包括版 本号和安装时启用的可选项。
Vary
Vary: Accept-Language
首部字段 Vary 可对缓存进行控制。源服务器会向代理服务器传达关 于本地缓存使用方法的命令。
从代理服务器接收到源服务器返回包含 Vary 指定项的响应之后,若 再要进行缓存,仅对请求中含有相同 Vary 指定首部字段的请求返回 缓存。即使对相同资源发起请求,但由于 Vary 指定的首部字段不相 同,因此必须要从源服务器重新获取资源。
实体首部字段
实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首 部,用于补充内容的更新时间等与实体相关的信息。
Allow
Allow: GET, HEAD
首部字段 Allow 用于通知客户端能够支持 Request-URI 指定资源的所 有 HTTP 方法。当服务器接收到不支持的 HTTP 方法时,会以状态码 405 Method Not Allowed 作为响应返回。与此同时,还会把所有能支 持的 HTTP 方法写入首部字段 Allow 后返回。
Content-Encoding
Content-Encoding: gzip
首部字段 Content-Encoding 会告知客户端服务器对实体的主体部分选 用的内容编码方式。内容编码是指在不丢失实体信息的前提下所进行 的压缩。
主要采用以下 4 种内容编码的方式:gzip 、 compress、 deflate 、identity
Content-Language
Content-Language: zh-CN
首部字段 Content-Language 会告知客户端,实体主体使用的自然语言 (指中文或英文等语言)。
Content-Length
Content-Length: 15000
首部字段 Content-Length 表明了实体主体部分的大小(单位是字 节)。对实体主体进行内容编码传输时,不能再使用 Content-Length 首部字段。
Content-Type
Content-Type: text/html; charset=UTF-8
首部字段 Content-Type 说明了实体主体内对象的媒体类型。和首部字 段 Accept 一样,字段值用 type/subtype 形式赋值。
Expires
Expires: Wed, 04 Jul 2012 08:26:05 GMT
首部字段 Expires 会将资源失效的日期告知客户端。缓存服务器在接 收到含有首部字段 Expires 的响应后,会以缓存来应答请求,在 Expires 字段值指定的时间之前,响应的副本会一直被保存。当超过 指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求 资源。
源服务器不希望缓存服务器对资源缓存时,最好在 Expires 字段内写 入与首部字段 Date 相同的时间值。
这是一个缓存字段,具体缓存机制可以参考HTTP缓存技术详解
Last-Modified
Last-Modified: Wed, 23 May 2012 09:59:55 GMT
首部字段 Last-Modified 指明资源最终修改的时间。一般来说,这个 值就是 Request-URI 指定资源被修改的时间。
这是一个缓存字段,具体缓存机制可以参考HTTP缓存技术详解
为Cookie服务的首部字段
Cookie 的工作机制是用户识别及状态管理。Web 网站为了管理用户的 状态会通过 Web 浏览器,把一些数据临时写入用户的计算机内。接 着当用户访问该Web网站时,可通过通信方式取回之前发放的 Cookie。
调用 Cookie 时,由于可校验 Cookie 的有效期,以及发送方的域、路 径、协议等信息,所以正规发布的 Cookie 内的数据不会因来自其他 Web 站点和攻击者的攻击而泄露。
首部字段名 | 说明 | 首部类型 |
---|---|---|
Set-Cookie | 开始状态管理所使用的Cookie信息 | 响应首部字段 |
Cookie | 服务器接收到的Cookie信息 | 请求首部字段 |
Set-Cookie
Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31
当服务器准备开始管理客户端的状态时,会事先告知各种信息。
Set-Cookie 字段的属性
属性 | 说明 |
---|---|
NAME=VALUE | 赋予 Cookie 的名称和其值(必需项) |
expires=DATE | Cookie 的有效期(若不明确指定则默认为浏览器关闭前为止) |
path=PATH | 将服务器上的文件目录作为Cookie的适用对象(若不指定则默 认为文档所在的文件目录) |
domain=域名 | 作为 Cookie 适用对象的域名 (若不指定则默认为创建 Cookie 的服务器的域名) |
Secure | 仅在 HTTPS 安全通信时才会发送 Cookie |
HttpOnly | 加以限制,使 Cookie 不能被 JavaScript 脚本访问 |
expires
Cookie 的 expires 属性指定浏览器可发送 Cookie 的有效期。 当省略 expires 属性时,其有效期仅限于维持浏览器会话(Session) 时间段内。这通常限于浏览器应用程序被关闭之前。 另外,一旦 Cookie 从服务器端发送至客户端,服务器端就不存在可 以显式删除 Cookie 的方法。但可通过覆盖已过期的 Cookie,实现对 客户端 Cookie 的实质性删除操作。
path
Cookie 的 path 属性可用于限制指定 Cookie 的发送范围的文件目录。 不过另有办法可避开这项限制,看来对其作为安全机制的效果不能抱 有期待。
domain
通过 Cookie 的 domain 属性指定的域名可做到与结尾匹配一致。比 如,当指定 example.com 后,除 example.com 以外,www.example.com 或 www2.example.com 等都可以发送 Cookie。
因此,除了针对具体指定的多个域名发送 Cookie 之 外,不指定 domain 属性显得更安全。
secure
Cookie 的 secure 属性用于限制 Web 页面仅在 HTTPS 安全连接时,才 可以发送 Cookie。
Set-Cookie: name=value; secure
HttpOnly
Cookie 的 HttpOnly 属性是 Cookie 的扩展功能,它使 JavaScript 脚本 无法获得 Cookie。其主要目的为防止跨站脚本攻击(Cross-site scripting,XSS)对 Cookie 的信息窃取。
Set-Cookie: name=value; HttpOnly
通过上述设置,通常从 Web 页面内还可以对 Cookie 进行读取操作。 但使用 JavaScript 的 document.cookie 就无法读取附加 HttpOnly 属性后 的 Cookie 的内容了。因此,也就无法在 XSS 中利用 JavaScript 劫持 Cookie 了。
Cookie
Cookie: status=enable
首部字段 Cookie 会告知服务器,当客户端想获得 HTTP 状态管理支 持时,就会在请求中包含从服务器接收到的 Cookie。接收到多个 Cookie 时,同样可以以多个 Cookie 形式发送。
作者:会飞小超人
链接:https://www.jianshu.com/p/1c7faf00a436
共同学习,写下你的评论
评论加载中...
作者其他优质文章