【网络协议笔记】HTTP 协议整理
2019-07-09 本文已影响2人
58bc06151329
文前说明
作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。
本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。
1. 概要
- 在多个端系统上的程序进行通信的实际上是 进程(process)而不是程序。在不同端系统上的进程,通过跨越计算机网络交换 报文(message)。
- 进程通过 套接字(socket)的软件接口向网络发送报文和从网络接收报文。
- 由于该套接字是建立网络应用程序的可编程接口,因此套接字也成为应用程序和网络之间的 应用程序编程接口(Application Programming Interface,API)。
- 因特网为应用程序提供两个运输层协议,TCP 和 UDP。
- TCP 服务模型包括 面向连接服务 和 可靠数据传输服务。
- 无论 TCP 还是 UDP 都没有提供任何加密机制,因为隐私和其他安全问题对许多应用而言已经成为至关重要的问题,所以研制了 TCP 的加强版本,成为 安全套接字层(Secure Socket Layer,SSL),SSL 不是与 TCP 和 UDP 在相同层次上第三种因特网运输协议,而是一种对 TCP 的加强,这种强化是在应用层上实现的。
- UDP 是一种不提供不需要服务的轻量级运输协议,仅提供最小服务,进程通信前没有握手过程,提供的是一种不可靠数据传送服务,并不保证报文将到达接收进程,而且到达接收进程的报文也可能是乱序到达的,UDP 没有拥塞控制机制,实际端到端吞吐量可能小于该速率(这可能是因为中间链路的带宽受限或因为拥塞而造成的)。
2. 原理
- Web 的应用层协议是 超文本传输协议(HyperText Transfer Protocol,HTTP),在 [ RFC 1945 ] 和 [ RFC 2616 ] 中进行了定义。
- HTTP 定义了 Web 客户向 Web 服务器请求 Web 页面的方式,以及服务器向客户传送 Web 页面的方式。
- HTTP 使用 TCP 作为它的支撑运输协议,HTTP 客户首先发起一个与服务器的 TCP 连接,一旦连接建立,该浏览器和服务器进程就可以通过套接字接口访问 TCP。
- HTTP 是一个 无状态协议(stateless protocol),HTTP 服务器并不保存关于客户的任何信息。
- HTTP 默认端口号为 80。
- HTTP 使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。
- HTTP 默认方式下使用持续连接,非持续连接有一些缺点。
- 第一,必须为每一个请求的对象建立和维护一个全新的连接,在客户和服务器中都要分配 TCP 的缓冲区和保持 TCP 变量,给 Web 服务器带来了严重的负担。
- 第二,每个对象经受两倍 RTT(从客户请求 HTML 基本文件起到该客户收到整个文件止所花费的时间,这是 往返时间(Round-Trip Time,RTT)的定义,该时间是指一个短分组从客户到服务器然后再返回客户所花费的时间,RTT 包括分组传播时延、分组在中间路由器和交换机上的排队时延以及分组处理时延) 的交付时延,即一个 RTT 用于创建 TCP,另一个 RTT 用于请求和接收一个对象。
- HTTP/2 [ RFC 7540 ] 是在 HTTP 1.1 基础上构建的,允许在相同连接中多个请求和回答交错,并增加了在该连接中优化 HTTP 报文请求和回答的机制。
2.1 报文格式
- HTTP 规范 [ RFC 1945;RFC 2616;RFC 7540 ] 包含了对 HTTP 报文格式的定义。
- HTTP 报文有两种,请求报文 和 响应报文。
- SP 为 White SPace 空格键,CR 为 Carriage return 回车键,LF 为 Line Feed 换行键。
2.1.1 请求报文
GET / HTTP/1.1
Host: server.example.com
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: <base64url encoding of HTTP/2 SETTINGS payload>
- 请求报文的第一行是 请求行(request line),其后继的行为 首部行(header line)。
- 请求行有 3 个字段,方法字段、URL 字段 和 HTTP 版本字段。

请求方法说明
- HTTP 协议中共定义了多种方法或者叫 " 动作 " 来表明对 Request-URI 指定的资源的不同操作方式。
- HTTP1.0 定义了三种请求方法: GET,POST 和 HEAD 方法。
- HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。
方法 | 说明 |
---|---|
PTIONS | 返回服务器针对特定资源所支持的 HTTP 请求方法。也可以利用向 Web 服务器发送 '*' 的请求来测试服务器的功能性。 |
HEAD | 向服务器索要与 GET 请求相一致的响应,只不过响应体将不会被返回。这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息。 |
GET | 向特定的资源发出请求。 |
POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的创建和/或已有资源的修改。 |
PUT | 向指定资源位置上传其最新内容。 |
DELETE | 请求服务器删除 Request-URI 所标识的资源。 |
TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
CONNECT | HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。 |
PATCH | 是对 PUT 方法的补充,用来对已知资源进行局部更新 。 |
2.1.2 响应报文
HTTP/1.1 200 OK
Content-Length: 243
Content-Type: text/html
- 响应报文包含 初始状态行(status line)、首部行(header line)和 实体体(entity body)。

HTTP 状态码分类
- HTTP 状态码由 3 个十进制数字组成,第 1 个十进制数字定义了状态码的类型。
分类 | 描述 |
---|---|
1** | 信息,服务器收到请求,需要请求者继续执行操作。 |
2** | 成功,操作被成功接收并处理。 |
3** | 重定向,需要进一步的操作以完成请求。 |
4** | 客户端错误,请求包含语法错误或无法完成请求。 |
5** | 服务器错误,服务器在处理请求的过程中发生了错误。 |
HTTP 状态码说明
状态码 | 英文名称 | 说明 |
---|---|---|
100 | Continue | 继续。客户端应继续其请求。 |
101 | Switching Protocols | 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到 HTTP 的新版本协议。 |
102 | Processing | 由 WebDAV(RFC 2518)扩展的状态码,代表处理将被继续执行。 |
200 | OK | 请求成功。一般用于 GET 与 POST 请求。 |
201 | Created | 已创建。成功请求并创建了新的资源。 |
202 | Accepted | 已接受。已经接受请求,但未处理完成。 |
203 | Non-Authoritative Information | 非授权信息。请求成功。但返回的 meta 信息不在原始的服务器,而是一个副本。 |
204 | No Content | 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档。 |
205 | Reset Content | 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域。 |
206 | Partial Content | 部分内容。服务器成功处理了部分 GET 请求。 |
207 | Multi-Status | 由 WebDAV(RFC 2518)扩展的状态码,代表之后的消息体将是一个 XML 消息,并且可能依照之前子请求数量的不同,包含一系列独立的响应代码。 |
300 | Multiple Choices | 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择。 |
301 | Moved Permanently | 永久移动。请求的资源已被永久的移动到新 URI,返回信息会包括新的 URI,浏览器会自动定向到新 URI。今后任何新的请求都应使用新的 URI 代替。对于某些使用 HTTP/1.0 协议的浏览器,当它们发送的 POST 请求得到了一个 301 响应的话,接下来的重定向请求将会变成 GET 方式。 |
302 | Found | 临时移动。与 301 类似。但资源只是临时被移动。客户端应继续使用原有 URI。 |
303 | See Other | 查看其它地址。与 301 类似。使用 GET 和 POST 请求查看。 |
304 | Not Modified | 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源。 |
305 | Use Proxy | 使用代理。所请求的资源必须通过代理访问。 |
306 | Unused | 已经被废弃的 HTTP 状态码。 |
307 | Temporary Redirect | 临时重定向。与 302 类似。使用 GET 请求重定向。 |
400 | Bad Request | 客户端请求的语法错误,服务器无法理解。 |
401 | Unauthorized | 请求要求用户的身份认证。 |
402 | Payment Required | 保留,将来使用。 |
403 | Forbidden | 服务器理解请求客户端的请求,但是拒绝执行此请求。 |
404 | Not Found | 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置 " 您所请求的资源无法找到 " 的个性页面。 |
405 | Method Not Allowed | 客户端请求中的方法被禁止。 |
406 | Not Acceptable | 服务器无法根据客户端请求的内容特性完成请求。 |
407 | Proxy Authentication Required | 请求要求代理的身份认证,与 401 类似,但请求者应当使用代理进行授权。 |
408 | Request Time-out | 服务器等待客户端发送的请求时间过长,超时。 |
409 | Conflict | 服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突。 |
410 | Gone | 客户端请求的资源已经不存在。410 不同于 404,如果资源以前有现在被永久删除了可使用 410 代码,网站设计人员可通过 301 代码指定资源的新位置。 |
411 | Length Required | 服务器无法处理客户端发送的不带 Content-Length 的请求信息。 |
412 | Precondition Failed | 客户端请求信息的先决条件错误。 |
413 | Request Entity Too Large | 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个 Retry-After 的响应信息。 |
414 | Request-URI Too Large | 请求的 URI 过长(URI 通常为网址),服务器无法处理。 |
415 | Unsupported Media Type | 服务器无法处理请求附带的媒体格式。 |
416 | Requested range not satisfiable | 客户端请求的范围无效。 |
417 | Expectation Failed | 服务器无法满足 Expect 的请求头信息。 |
421 | Too Many Connections | 从当前客户端所在的 IP 地址到服务器的连接数超过了服务器许可的最大范围。 |
422 | Unprocessable Entity | 请求格式正确,但是由于含有语义错误,无法响应。(RFC 4918 WebDAV) |
423 | Locked | 当前资源被锁定。(RFC 4918 WebDAV) |
424 | Failed Dependency | 由于之前的某个请求发生的错误,导致当前请求失败,例如 PROPPATCH。(RFC 4918 WebDAV) |
425 | Unordered Collection | 在 WebDav Advanced Collections 草案中定义,但是未出现在《WebDAV 顺序集协议》(RFC 3658)中。 |
426 | Upgrade Required | 客户端应当切换到 TLS/1.0。(RFC 2817) |
449 | Retry With | 由微软扩展,代表请求应当在执行完适当的操作后进行重试。 |
451 | Unavailable For Legal Reasons | 该请求因法律原因不可用。(RFC 7725) |
500 | Internal Server Error | 服务器内部错误,无法完成请求。 |
501 | Not Implemented | 服务器不支持请求的功能,无法完成请求。 |
502 | Bad Gateway | 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应。 |
503 | Service Unavailable | 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的 Retry-After 头信息中。 |
504 | Gateway Time-out | 充当网关或代理的服务器,未及时从远端服务器获取请求。 |
505 | HTTP Version not supported | 服务器不支持请求的 HTTP 协议的版本,无法完成处理。 |
506 | Variant Also Negotiates | 由《透明内容协商协议》(RFC 2295)扩展,代表服务器存在内部配置错误。 |
507 | Insufficient Storage | 服务器无法存储完成请求所必须的内容。这个状况被认为是临时的。WebDAV (RFC 4918) |
509 | Bandwidth Limit Exceeded | 服务器达到带宽限制。这不是一个官方的状态码,但是仍被广泛使用。 |
510 | Not Extended | 获取资源所需要的策略并没有没满足。(RFC 2774) |
600 | Unparseable Response Headers | 源站没有返回响应头部,只返回实体内容。 |
2.1.3 首部字段
2.1.3.1 通用首部字段
首部字段名称 | 说明 |
---|---|
Cache-Control | 控制缓存的行为。 |
Connection | 逐跳首部、连接的管理。 |
Date | 创建报文的日期时间。 |
Pragma | 报文指令。 |
Trailer | 报文末端的首部一览。 |
Transfer-Encoding | 指定报文主体的传输编码方式。 |
Upgrade | 升级为其他协议。 |
Via | 代理服务器的相关信息。 |
Waring | 错误通知。 |
2.1.3.1.1 Cache-Control
- 通过指定首部字段 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)。 |
表示是否能缓存的指令
当指定 public 指令时,则明确表示其他用户也可利用缓存。
Cache-Control:public
- 当指定 private 指令时,响应只以特定的用户作为对象,这与 public 指令的行为相反。
- 缓存服务器会对该用户提供资源缓存的服务,对于其他用户发送过来的请求,代理服务器不会返回缓存。
Cache-Control:private
- no-cache 指令的目的是为了防止从缓存中返回过期的资源,缓存会向源服务器进行有效期确认后处理资源。
- 客户端发送的请求中如果包含 no-cache 指令,则表示客户端不会接收缓存过的响应,缓存服务器必须把客户端请求转发给源服务器。
- 从源服务器返回最新资源后,缓存服务器依然可以将最新资源进行缓存,然后再返回给客户端,除非服务器端也返回 no-cache 指令。
- 服务端返回的响应中如果包含 no-cache 指令,那么缓存服务器不能对资源进行缓存,源服务器以后也不会再对缓存服务器请求中提出的资源有效性进行确认。
Cache-Control:no-cache
- 只能在响应指令中指定该参数,通过服务器端返回的指令来确定客户端是否可以使用缓存。
- 客户端在接收到这个被指定参数值的报文首部后,就不能使用缓存。换句话说,无参数值的首部字段可以使用缓存。
Cache-Control:no-cache=Location
- 暗示请求或响应中包含机密信息,该指令规定不进行任何缓存。
Cache-Control:no-store
指定缓存期限和认证的指令
- 与 max-age 的指令相同,不同点是 s-maxage 只适用于供多位用户使用的公共缓存服务器。对于向同一用户重复返回响应的服务器来说,这个指令没有任何作用。
- 使用这个指令后,会直接忽略对 Expires 首部字段及 max-age 指令的处理。
- 单位:秒。
Cache-Control:s-maxage=3600
- 当客户端发送的请求中包含该指令时,如果判定缓存资源的缓存时间比指定的时间数值更小,那么客户端就接收缓存的资源。如果 max-age 的值为 0,那么缓存服务器需要将请求转发给源服务器。
- 当服务器返回的响应中包含该指令时,缓存服务器将不会对资源的有效性进行确认,此时 max-age 代表资源保存为缓存的最长时间。
- HTTP/1.1 版本的缓存服务器遇到同时存在 Expires 首部字段的情况时,会优先处理 max-age 指令,而忽略掉 Expires 首部字段。但是 HTTP/1.0 版本的缓存服务器情况却相反,max-age 指令会被忽略掉。
- 单位:秒。
Cache-Control:max-age=3600
- 指令要求缓存服务器返回还未过指定时间的缓存资源。
- 单位:秒。
Cache-Control:min-fresh=60
- 指示缓存资源,即使过期,但只要处于 max-stale 指定的时间内仍然会被客户端照常接收。
- 如果该指令未指定相应参数,那么无论过了多久,客户端都会接收响应。
- 单位:秒。
Cache-Control:max-stale=3600
- 该指令要求缓存服务器不重新加载响应,也不会再次确认资源有效性,如果请求缓存服务器的本地缓存无响应,则返回状态码 504。
Cache-Control:only-if-cached
- 使用该指令时,代理会向源服务器再次验证即将返回的响应缓存目前是否仍然有效,若代理无法连接源服务器获取有效资源的话,缓存必须给客户端一个 504 的状态码。
- 另外,使用该指令将忽略请求的 max-stale 指令。
Cache-Control:must-revalidate
- 当客户端的请求包含该指令时,缓存服务器在返回响应之前,必须再次验证缓存的有效性。
Cache-Control:no-transform
- 通过 cache-extension 标记(token),可以扩展 Cache-Control 首部字段内的指令。
- 如添加了 community 这个新指令,如果缓存服务器不能够理解 community 这个新指令,就会直接忽略。因此 extension tokens 仅对能理解它的缓存服务器有效。
Cache-Control:private,community="UCI"
2.1.3.1.2 Connection
控制不再转发给代理的首部字段
Connection:Upgrade (不再转发的首部字段名)
//操作方式是将首部字段 Upgrade 删除后再转发
管理持久连接
- HTTP/1.1 版本的默认连接都是持久连接(长连接),然后客户端会在持久连接上连续发送请求,当服务器想明确断开连接时,则指定 Connection 首部字段为 Close。
Connection:Close
- HTTP/1.1 之前的版本默认的都是非持久连接(短连接),如果想在旧版本的 HTTP 协议上维持持续连接,则需要指定 Connection 的值为 Keep-Alive。
Keep-Alive:timeout=10,max=500
Connection:Keep-Alive
2.1.3.1.3 Date
- HTTP/1.1 协议使用 RFC1123 中规定的日期时间的格式。
Date:Tue,03 Jul 2012 04:40:59 GMT
- HTTP/1.1 之前的协议使用 RFC850 中定义的格式。
Date:Tue,03-Jul-12 04:40:59 GMT
2.1.3.1.4 Pragma
- 用在客户端发送的请求中,客户端会要求所有的中间服务器不返回缓存的资源。
Pragma:no-cache
- 是 HTTP/1.1 之前版本的历史遗留字段,仅作为 HTTP/1.0 的向后兼容。
- 如果所有的中间服务器都使用 HTTP/1.1 版本协议的话,那么直接使用 Cache-Control:no-cache 是最理想的,但所有的中间服务器使用的 HTTP 协议版本并不完全一致。因此,发送的请求会同时含有下面两个字段。
Cache-Control:no-cache
Pragma:no-cache
2.1.3.1.5 Trailer
- 此字段会事先说明在报文主体后记录了哪些首部字段,可用于 HTTP/1.1 版本分块传输编码时。

- 指定首部字段 Trailer 的值为 Expires,在报文主体之后(分块长度 0 之后)出现了首部字段 Expires。
2.1.3.1.6 Transfer-Encoding
- 此字段规定了传输报文主体时使用的编码方式,HTTP/1.1 的传输编码方式仅对分块传输编码有效。

2.1.3.1.7 Upgrade
- 此字段用于检测 HTTP 协议及其他协议是否可以使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议。
- Upgrade 对象仅限于客户端和邻接服务器之间,因此,在使用了 Upgrade 时,还需要额外指定 Connection:Upgrade,对于附有 Upgrade 字段的请求,服务端可使用 101 状态码作为响应返回。
2.1.3.1.8 Via
- 此字段是为了追踪客户端与服务端之间的请求和响应报文的传输路径。报文在经过代理或网关时,会先在首部字段 Via 中附加该服务器的信息,然后再进行转发,使用它可以避免回环的发生,所以必须在经过代理时附加该首部字段内容。
- Via 首部为了追踪传输路径,经常会和 TRACE 方法一起使用。比如,代理服务器接收到由 TRACE 方法发送过来的请求(Max-Forwards:0)时,代理服务器就不能转发该请求了,这种情况下,代理服务器会将自身的信息附加到 Via 首部后,返回该请求的响应。
2.1.3.1.9 Warnning
- 该首部字段通常会告知用户一些与缓存相关的一些问题的警告。
- 格式:Warning:[警告码][警告的主机:端口号]"[警告内容]"
- HTTP/1.1 中定义了 7 种警告。
警告码 | 警告内容 | 说明 |
---|---|---|
110 | Response is stale(响应已过期) | 代理返回已过期的资源。 |
111 | Revalidation failed(再验证失败) | 代理再验证资源有效性时失败(服务器无法到达等原因)。 |
112 | Disconnectio operation(断开连接操作) | 代理与互联网连接被故意切断。 |
113 | Heuristic expiration(试探性过期) | 响应的使用期超过 24 小时(有效缓存的设定时间大于 24 小时的情况下)。 |
199 | Miscellaneous warning(杂项警告) | 任意的警告内容。 |
214 | TransFormaction applied(使用了转换) | 代理对内容编码或媒体类型等执行了某些处理时。 |
299 | Miscellaneous persistent warning(持久杂项警告) | 任意的警告内容。 |
2.1.3.2 请求首部字段
- 请求首部字段是从客户端往服务端发送请求报文中所使用的字段,用于补充请求的附加信息、客户端信息、对响应内容的优先级等内容。
首部字段名称 | 说明 |
---|---|
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 客户端程序的信息。 |
2.1.3.2.1 Accept
- 该首部字段可通知服务器,用户代理能处理的媒体类型以及媒体类型的相对优先级,可使用 type/subtype 这种形式,一次指定多种媒体类型。
- 如果想要给显示的媒体类型增加优先级,就使用 q= 来额外表示权重值,用 " ; " 进行分隔。
- 权重值 q 的范围是 0~1(可精确到小数点后三位),且 1 为最大值。
- 不指定权重值时,默认 q=1.0。
- 当服务器提供多种内容时,将会首先返回媒体值最高的类型。
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
2.1.3.2.2 Accept-Charset
- 该首部字段可用来通知服务器用户代理支持的字符集及字符集的相对优先级顺序。同样,可一次性指定多个字符集,用 q= 来表示字符集的相对优先级。
Accept-Charset:iso-8859-5,unicode-1-1;q=0.8
2.1.3.2.3 Accept-Encoding
- 该首部字段可用来通知服务器用户代理支持的内容编码及内容编码的优先级顺序。同样,可一次性指定多种内容编码,用 q= 来表示内容编码的相对优先级。
Accept-Encoding:gzip,deflate
2.1.3.2.4 Accept-Language
- 该首部字段告知服务器用户代理能够处理的自然语言集以及自然语言集的相对优先级。同样,可一次指定多种自然语言集,用 q= 来表示自然语言集的相对优先级。
Accept-Language:zh-cn,zh;q=0.7,en-us,en;q=0.3
2.1.3.2.5 Authorization
- 该首部字段用来告知服务器用户代理的认证信息。通常,想要通过服务器认证的用户代理会在接收到返回的 401 状态码响应之后,把首部字段 Authorization 加入请求中。共用缓存在接收到含有 Authorization 首部字段的请求时的操作处理有所差异。
Authorization:Basic dWVub3N1bjpwYXNzd29yZA==
2.1.3.2.6 From
- 该首部字段用来告知服务器使用代理的用户的电子邮件地址。通常,使用目的就是为了显示搜索引擎等用户代理的负责人的电子邮件联系方式。使用代理时,应尽可能使用该字段,但有的代理可能会将电子邮件地址在 User-Agent 首部字段内。
From:info@qq.com
2.1.3.2.7 Host
- 该首部字段会告知服务器,请求的资源所处的互联网主机名和端口号。它是 HTTP/1.1 规范中唯一一个必须包含在请求内的首部字段。
- 由于相同的 IP 地址下可能会部署运行多个域名,服务器就会无法理解究竟是哪个域名对应的请求,因此就需要使用此字段来明确的指出请求的主机名。如果服务器没有设定主机名,那直接发送一个空值即可。
Host:www.adcd.com
2.1.3.2.8 If-Match
- 形如 If-xxx 这种形式的请求首部字段,都可称为条件请求,服务器接收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。
- 该首部字段会告知服务器匹配资源所使用的实体标记(ETag)值,这时的服务器无法使用弱 ETag 值。服务器会比对 If-Match 的字段值和资源的 ETag 值,仅当再者一致时,才会执行请求。反之,则返回状态码 412 的响应。也可以使用" * "来指定 If-Match 的字段值,这时服务器将会忽略 ETag 的值,只要资源存在就处理请求。
If-Match:"123456"
2.1.3.2.9 If-None-Match
- 该首部字段与 If-Match 的作用相反。
If-None-Match:*
2.1.3.2.10 If-Modified-Since
- 该首部字段用于确认代理或客户端拥有的本地资源的有效性。它会告知服务器在些字段指定的时间后资源发生了更新就处理该请求,如果请求的资源没有更新过,则返回状态码 304 的响应。
If-Modified-Since:Thu,15 Apr 2004 00:00:00 GMT
2.1.3.2.11 If-Unmodified-Since
- 该首部字段与 If-Modified-Since 的作用相反。
If-Modified-Since:Thu,15 Apr 2004 00:00:00 GMT
2.1.3.2.12 If-Range
- 该首部字段属于附带条件之一,它告诉服务器若指定的 If-Range 值(ETag 值或时间)和请求资源的 ETag 值或时间相同时,则作为范围请求处理。否则,返回全体资源。
- 如果不使用该首部字段,就需要两次处理。
If-Range:"123456"
Range:bytes=5001-10000
2.1.3.2.13 Max-Forwards
- 通过 Trace 或 Options 的方法发送包含该首部字段的请求时,该字段以十进制整数形式指定可经过的服务器最大数目。服务器在往下一下服务器转发请求之前,会将该首部字段的值减 1 后重新赋值。当值为 0 时,请求不再进行转发,而是直接返回响应。
Max-Forwards:10
2.1.3.2.14 Proxy-Authorization
- 客户端接收到从代理服务器发送过来的认证质询时,客户端会发送包含该首部字段的请求,以告知服务器认证所需要的信息。
Proxy-Authorization: Basic dGlwOjkpNLAGfFY5
2.1.3.2.15 Range
- 客户端发送带有该首部字段的请求可以指定服务器资源的范围。接收到该首部字段的服务器,会在处理请求之后返回状态码为 206 Partial Content 的响应,如果无法处理该范围请求,则会返回状态码为 200 OK 的响应及全部资源。
Range:bytes=5001-10000
2.1.3.2.16 Referer
- 该首部字段会告知服务器请求的原始资源的 URI。
Referer: http://www.hackr.jp/index.htm
2.1.3.2.17 TE
- 该首部字段会告知服务器客户端能够处理响应的传输编码方式以及相对优先级,它和 Accept-Encoding 的功能很像,但是 TE 只是用于传输编码。
- 首部字段 TE 除指定传输编码之外,还可以指定伴随 trailer 字段的分块传输编码的方式。这时需要把 trailers 赋值给该字段值。
TE: gzip, deflate;q=0.5
2.1.3.2.18 User-Agent
- 该首部字段将会创建请求的浏览器和用户代理名称等信息传达给服务器。
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/201001
2.1.3.3 响应首部字段
- 响应首部字段是由服务器端向客户端返回响应报文中所使用的字段,用于补充响应的附加信息、服务器信息,以及对客户端的附加要求等信息。
首部字段名称 | 名称 |
---|---|
Accept-Ranges | 是否接受字节范围请求。 |
Age | 推算资源创建经过时间。 |
ETag | 资源的匹配信息。 |
Location | 令客户端重定向至指定 URI。 |
Proxy-Authenticate | 代理服务器对客户端的认证信息。 |
Retry-After | 对再次发起请求的时机要求。 |
Server | HTTP 服务器的安装信息。 |
Vary | 代理服务器缓存的管理信息。 |
WWW-Authenticate | 服务器对客户端的认证信息。 |
2.1.3.3.1 Accept-Ranges
- 该首部字段是用于告知客户端服务器是否能处理范围请求,以指定获取服务器端某个部分的资源。它可以指定的字段值有两种,可处理范围请求时指定其为 bytes,反之则指定为 none。
Accept-Ranges: bytes
2.1.3.3.2 Age
- 该首部字段可以告知客户端,源服务器在多久前创建了响应,字段值的单位为秒。
- 若创建该响应的服务器是缓存服务器,Age 值是指缓存后的响应再次发起认证到认证完成的时间值。
- 代理创建响应时必须加上首部字段 Age。
Age:600
2.1.3.3.3 ETag
- 首部字段 ETag 能告知客户端实体标识。它是一种可将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的 ETag 值。
ETag: "82e22293907ce725faf67773957acd12"
- 强 ETag 值,不论实体发生多么细微的变化都会改变其值。
ETag: "usagi-1234"
- 弱 ETag 值只用于提示资源是否相同。只有资源发生了根本改变,产生差异时才会改变 ETag 值。这时,会在字段值最开始处附加 W/。
ETag: W/"usagi-1234"
Proxy-Authenticate: Basic realm="Usagidesign Auth"
2.1.3.3.4 Location
- 使用首部字段 Location 可以将响应接收方引导至某个与请求 URI 位置不同的资源。基本上,该字段会配合 3xx :Redirection 的响应,提供重定向的 URI。几乎所有的浏览器在接收到包含首部字段 Location 的响应后,都会强制性地尝试对已提示的重定向资源进行访问。
Location: http://www.usagidesign.jp/sample.html
2.1.3.3.5 Proxy-Authenticate
- 该首部字段会把由代理服务器所要求的认证信息发送给客户端。它与客户端和服务器之间的 HTTP 访问认证的行为相似,不同之处在于其认证行为是在客户端与代理之间进行的。而客户端与服务器之间进行认证时,首部字段 WWW-Authorization 有着相同的作用。
Proxy-Authenticate: Basic realm="Usagidesign Auth"
2.1.3.3.6 Retry-After
- 该首部字段告知客户端应该在多久之后再次发送请求。主要配合状态码 503 Service Unavailable 响应,或 3xx Redirect 响应一起使用。
- 字段值可以指定为具体的日期时间(Wed, 04 Jul 2012 06:34:24GMT 等格式),也可以是创建响应后的秒数。
Retry-After: 120
2.1.3.3.7 Server
- 该首部字段告知客户端当前服务器上安装的 HTTP 服务器应用程序的信息。不单单会标出服务器上的软件应用名称,还有可能包括版本号和安装时启用的可选项。
Server: Apache/2.2.17 (Unix)
2.1.3.3.8 Vary
- 当代理服务器接收到带有 Vary 首部字段指定获取资源的请求时,如果与使用的 Accept-Language 字段的值相同,那么就直接从缓存返回响应。反之,则需要先从源服务器端获取资源后才能作为响应返回。
- 首部字段 Vary 可对缓存进行控制。源服务器会向代理服务器传达关于本地缓存使用方法的命令。从代理服务器接收到源服务器返回包含 Vary 指定项的响应之后,若再要进行缓存,仅对请求中含有相同 Vary 指定首部字段的请求返回缓存。即使对相同资源发起请求,但由于 Vary 指定的首部字段不相同,因此必须要从源服务器重新获取资源。
Vary: Accept-Language
2.1.3.3.9 WWW-Authenticate
- 该首部字段用于 HTTP 访问认证。它会告知客户端适用于访问请求 URI 所指定资源的认证方案(Basic 或是 Digest)和带参数提示的质询(challenge)。状态码 401 Unauthorized 响应中,肯定带有首部字段 WWW-Authenticate。
WWW-Authenticate: Basic realm="Usagidesign Auth"
2.1.3.4 实体首部字段
- 实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。
首部字段名称 | 说明 |
---|---|
Allow | 资源可支持的 HTTP 方法。 |
Content-Encoding | 实体主体适用的编码方式。 |
Content-Language | 实体主体的自然语言。 |
Content-Location | 替代对应资源的 URI。 |
Content-MD5 | 实体主体的报文摘要。 |
Content-Range | 实体主体的位置范围。 |
Content-Type | 实体主体的媒体类型。 |
Expires | 实体主体过期的日期时间。 |
Last-Modified | 资源的最后修改日期时间。 |
2.1.3.4.1 Allow
- 该首部字段用于通知客户端能够支持 Request-URI 指定资源的所有 HTTP 方法。当服务器接收到不支持的 HTTP 方法时,会以状态码 405 Method Not Allowed 作为响应返回。与此同时,还会把所有能支持的 HTTP 方法写入首部字段 Allow 后返回。
Allow: GET, HEAD
2.1.3.4.2 Content-Encoding
- 该首部字段会告知客户端服务器对实体的主体部分选用的内容编码方式。内容编码是指在不丢失实体信息的前提下所进行的压缩。
- 主要采取 4 种方式的压缩:gzip、compress、deflate、identity。
Content-Encoding: gzip
2.1.3.4.3 Content-Language
- 该首部字段会告知客户端,实体主体使用的自然语言(指中文或英文等语言)。
Content-Language: zh-CN
2.1.3.4.4 Content-Length
- 首部字段 Content-Length 表明了实体主体部分的大小(单位是字节)。对实体主体进行内容编码传输时,不能再使用 Content-Length 首部字段。
Content-Length: 15000
2.1.3.4.5 Content-Location
- 该首部字段给出与报文主体部分相对应的 URI。和首部字段 Location 不同,Content-Location 表示的是报文主体返回资源对应的 URI。
Content-Location: http://www.hackr.jp/index-ja.html
2.1.3.4.6 Content-MD5
- 该首部字段是一串由 MD5 算法生成的值,其目的在于检查报文主体在传输过程中是否保持完整,以及确认传输到达。
- 对报文主体执行 MD5 算法获得的 128 位二进制数,再通过 Base64 编码后将结果写入 Content-MD5 字段值。由于 HTTP 首部无法记录二进制值,所以要通过 Base64 编码处理。为确保报文的有效性,作为接收方的客户端会对报文主体再执行一次相同的 MD5 算法。计算出的 125 值与字段值作比较后,即可判断出报文主体的准确性。
- 采用这种方法,对内容上的偶发性改变是无从查证的,也无法检测出恶意篡改。其中一个原因在于,内容如果能够被篡改,那么同时意味着 Content-MD5 也可重新计算然后被篡改。所以处在接收阶段的客户端是无法意识到报文主体以及首部字段 Content-MD5 是已经被篡改过的。
Content-MD5: OGFkZDUwNGVhNGY3N2MxMDIwZmQ4NTBmY2IyTY==
2.1.3.4.7 Content-Range
- 针对范围请求,返回响应时使用的首部字段 Content-Range,能告知客户端作为响应返回的实体的哪个部分符合范围请求。字段值以字节为单位,表示当前发送部分及整个实体大小。
Content-Range: bytes 5001-10000/10000
2.1.3.4.8 Content-Type
- 该首部字段说明了实体主体内对象的媒体类型。和首部字段 Accept 一样,字段值用 type/subtype 形式赋值。参数 charset 使用 iso-8859-1 或 euc-jp 等字符集进行赋值。
Content-Type: text/html; charset=UTF-8
2.1.3.4.8 Expires
- 首部字段 Expires 会将资源失效的日期告知客户端。缓存服务器在接收到含有首部字段 Expires 的响应后,会以缓存来应答请求,在Expires 字段值指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源。源服务器不希望缓存服务器对资源缓存时,最好在 Expires 字段内写入与首部字段 Date 相同的时间值。但是,当首部字段 Cache-Control 有指定 max-age 指令时,比起首部字段 Expires,会优先处理 max-age 指令。
Expires: Wed, 04 Jul 2012 08:26:05 GMT
2.1.3.4.9 Last-Modified
- 该首部字段指明资源最终修改的时间。一般来说,这个值就是 Request-URI 指定资源被修改的时间。但类似使用 CGI 脚本进行动态数据处理时,该值有可能会变成数据最终修改时的时间。
Last-Modified: Wed, 23 May 2012 09:59:55 GMT
2.1.3.5 为 Cookie 服务的首部字段
- 管理服务器与客户端之间状态的 Cookie,虽然没有被编入标准化 HTTP/1.1 的 RFC2616 中,但在 Web 网站方面得到了广泛的应用。
- Cookie 的工作机制是用户识别及状态管理。Web 网站为了管理用户的状态会通过 Web 浏览器,把一些数据临时写入用户的计算机内。接着当用户访问该 Web 网站时,可通过通信方式取回之前发放的 Cookie。
- 调用 Cookie 时,由于可校验 Cookie 的有效期,以及发送方的域、路径、协议等信息,所以正规发布的 Cookie 内的数据不会因来自其他 Web 站点和攻击者的攻击而泄露。
2.1.3.5.1 Set-Cookie
- 响应首部字段。当服务器准备开始管理客户端的状态时,会事先告知各种信息。
Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31 GMT; pat
属性 | 说明 |
---|---|
NAME=VALUE | 赋予 Cookie 的名称和其值(必需项)。 |
expires=DATE | Cookie 的有效期(若不明确指定则默认为浏览器关闭前为止)。 |
path=PATH | 将服务器上的文件目录作为 Cookie 的适用对象(若不指定则默认为文档所在的文件目录)。 |
domain=域名 | 作为 Cookie 适用对象的域名(若不指定则默认为创建 Cookie 的服务器的域名)。 |
Secure | 仅在 HTTPS 安全通信时才会发送 Cookie。 |
HttpOnly | 加以限制,使 Cookie 不能被 JavaScript 脚本访问。 |
2.1.3.5.2 Cookie
- 请求首部字段。首部字段 Cookie 会告知服务器,当客户端想获得 HTTP 状态管理支持时,就会在请求中包含从服务器接收到的 Cookie。接收到多个Cookie 时,同样可以以多个 Cookie 形式发送。
Cookie: status=enable
2.1.3.6 其他首部字段
- HTTP 首部字段是可以自行扩展。
- 非正式的首部字段统一归纳在 RFC4229 HTTP Header Field Registrations 中。
2.1.3.6.1 X-Frame-Options
- 首部字段 X-Frame-Options 属于 HTTP 响应首部,用于控制网站内容在其他 Web 网站的 Frame 标签内的显示问题。其主要目的是为了防止点击劫持(clickjacking)攻击。
- 它有两个可指定的字段值,一是DENY :拒绝。
- 二是 SAMEORIGIN :仅同源域名下的页面(Top-level-browsingcontext)匹配时许可。
X-Frame-Options: DENY
2.1.3.6.2 X-XSS-Protection
- 首部字段 X-XSS-Protection 属于 HTTP 响应首部,它是针对跨站脚本攻击(XSS)的一种对策,用于控制浏览器 XSS 防护机制的开关。
- 首部字段 X-XSS-Protection 可指定的字段值如下。
- 0 :将 XSS 过滤设置成无效状态。
- 1 :将 XSS 过滤设置成有效状态。
- 首部字段 X-XSS-Protection 可指定的字段值如下。
X-XSS-Protection: 1
2.1.3.6.3 DNT
- 首部字段 DNT 属于 HTTP 请求首部,其中 DNT 是 Do Not Track 的简称,意为拒绝个人信息被收集,是表示拒绝被精准广告追踪的一种方法。
- 首部字段 DNT 可指定的字段值有两个,0 :同意被追踪,1 :拒绝被追踪。
DNT: 1
2.1.3.6.4 P3P
- 首部字段 P3P 属于 HTTP 相应首部,通过利用 P3P(The Platform forPrivacy Preferences,在线隐私偏好平台)技术,可以让 Web 网站上的个人隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的目的。
P3P: CP="CAO DSP LAW CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa OUR BUS I
- 协议中对 X- 前缀的废除在 HTTP 等多种协议中,通过给非标准参数加上前缀 X-,来区别于标准参数,并使那些非标准的参数作为扩展变成可能。
- 但是在 “ RFC 6648 - Deprecatingthe "X-" Prefix and Similar Constructs in Application Protocols ” 中提议停止该做法。
- 对已经在使用中的 X- 前缀来说,不应该要求其变更。
2.1.3.7 浏览器的同源策略及跨域请求
- 具有相同协议,域名和端口的页面,则具有相同的源,即它们是来自同一个服务的资源。
- 端口和协议的不同,只能通过后台来解决。
- 域名和实际 IP 地址不同属于跨域。localhost 和 127.0.0.1 虽然都指向本机,但也属于跨域。
- 浏览器的同源策略限制了从同一个源加载的资源 (文档或脚本等) 如何与来自另一个源的资源进行交互,它是一个用于隔离潜在恶意文件的重要安全机制。
- 同源策略控制了不同源之间的交互,当浏览器从一个源的网页去请求另一个源的资源时,即浏览器在做跨服务的资源访问时,就会出现跨域问题。
- 同源策略及跨域问题只是浏览器设计的一种安全机制,对于其他工具如 curl 则完全没有同源及跨域的概念。
- 浏览器在跨域请求资源时,实际的请求会被发送到被请求的服务端,响应也会被接收,只是如果不做跨域处理时,返回的响应不会被浏览器解析,同时浏览器会抛出跨域受限的错误。
CORS 的预请求
- 在跨域时,并不是所用的方法都会被允许,对于非默认允许方法,需要经过近一步验证后才会得到跨域允许,这就涉及到 CORS 的预请求。
- 在跨域时默认允许的 Method 有 GET、HEAD 和 POST。
- 在跨域时默认允许的 Content-Type 有 text/plain、multipart/form-data 和 application/x-www-form-urlencoded。
- 在跨域时默认允许的 对 CORS 安全的首部字段集合。
- 跨域时其它的限制包含有:请求头的限制、XMLHttpRequestUpload 对象均没有注册任何事件监听器和 请求中没有使用 ReadableStream 对象。
- CORS 预请求 (prefligt 请求) 就是浏览器在在发生请求时,会预先自动发出一个 OPTIONS 请求来检测本次请求中涉及到的一些内容(如 Method、Content-Type 等)是否被服务器接受。
- 一个 OPTIONS 请求一般会携带两个与跨域相关相关的头。
首部字段名称 | 说明 |
---|---|
Access-Control-Request-Method | 本次预请求的请求方法。 |
Access-Control-Request-Headers | 本次请求所携带的自定义首部字段。 |
- 服务端收到该预请求后,会返回相关的响应头。
首部字段名称 | 说明 |
---|---|
Access-Control-Allow-Origin | 服务器允许的跨域请求源。 |
Access-Control-Allow-Methods | 服务器允许的请求方法。 |
Access-Control-Allow-Headers | 服务器允许的自定义的请求首部字段。 |
- 通过预请求后,浏览器就会发生正式的数据请求。
- 整个请求过程其实是发生了两次请求,一次预请求,一次预请求通过后的实际数据请求。
- 预检请求只是一个检查的过程,不会携带任何请求的参数,预检通过后的请求才会真正的携带请求参数与服务器进行数据通信。
- 若服务器对预请求没有任何响应,那么浏览器不知道服务器是否支持跨域访问,就不会发送后续的实际请求,或者服务器不支持当前的 Origin 跨域访问也不会发送后续请求。
2.1.3.7.1 HTTP 请求首部字段
Origin
- 表明预检请求或实际请求的源站。
- origin 参数的值为源站 URI。它不包含任何路径信息,只是服务器名称。
- 有时候将该字段的值设置为空字符串是有用的,例如,当源站是一个 data URL 时。
- 不管是否为跨域请求,Origin 字段总是被发送。
Origin: <origin>
Access-Control-Request-Method
- 用于预检请求。其作用是,将实际请求所使用的 HTTP 方法告诉服务器。
Access-Control-Request-Method: <method>
Access-Control-Request-Headers
- 用于预检请求。其作用是,将实际请求所携带的首部字段告诉服务器。
Access-Control-Request-Headers: <field-name>[, <field-name>]*
2.1.3.7.2 HTTP 响应首部字段
Access-Control-Allow-Origin
- origin 参数的值指定了允许访问该资源的外域 URI。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符,表示允许来自所有域的请求。
- 如果服务端指定了具体的域名而非 “*”,那么响应首部中的 Vary 字段的值必须包含 Origin。这将告诉客户端:服务器对不同的源站返回不同的内容。
Access-Control-Allow-Origin: <origin> | *
Access-Control-Expose-Headers
- 在跨域访问时,XMLHttpRequest 对象的 getResponseHeader() 方法只能拿到一些最基本的响应头,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要访问其他头,则需要服务器设置本响应头。
- Access-Control-Expose-Headers 让服务器把允许浏览器访问的头放入白名单。
- 这样浏览器就能够通过 getResponseHeader 访问 X-My-Custom-Header 和 X-Another-Custom-Header 响应头了。
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
Access-Control-Max-Age
- 指定了 preflight 请求的结果能够被缓存多久。
- delta-seconds 参数表示 preflight 请求的结果在多少秒内有效。
Access-Control-Max-Age: <delta-seconds>
Access-Control-Allow-Credentials
- 指定了当浏览器的 credentials 设置为 true 时是否允许浏览器读取 response 的内容。当用在对 preflight 预检测请求的响应中时,它指定了实际的请求是否可以使用 credentials。请注意:简单 GET 请求不会被预检;如果对此类请求的响应中不包含该字段,这个响应将被忽略掉,并且浏览器也不会将相应内容返回给网页。
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods
- 用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法。
Access-Control-Allow-Methods: <method>[, <method>]*
Access-Control-Allow-Headers
- 用于预检请求的响应。其指明了实际请求中允许携带的首部字段。
Access-Control-Allow-Headers: <field-name>[, <field-name>]*