【读】这一次,让我们再深入一点 - HTTP报文

这是关于网络系列的第六篇文章,接下来会有更多精彩内容.敬请期待! 让我们一起乘风破浪!

HTTP 报文是客户端和服务器交流使用的“对话方式”,彼此说对方都能理解的话,才能相互沟通。就像 TCP 使用 TCP 报文交流一样.那么 HTTP 报文的格式到底怎样,让我们一探究竟!在本篇中,你将了解到一下内容:

  • 报文的流动方式
  • 报文的组成部分
  • 请求报文和响应报文的区别
  • 请求报文的各种功能
  • 状态码的含义
  • HTTP 首部是用来做什么的

了解报文流的概念

HTTP 报文在客户端、服务器、和代理之间的传递可以形象的称为流动。术语“流入”、“流出”、“上游”、“下游”是在的基础上定义的,用来描述报文方向。

  • “流入”意为报文从客户端到达服务器;“流出”,则和流入相反。可以看出,这两个术语是针对服务器而言。
  • “上游”和“下游”,不管是请求报文还是响应报文,所有报文都会向“下游”流动。所有报文的发送者都在接收者的“上游”。

报文的格式

开篇的图片很好的说明了 HTTP 报文的基本格式。

1
2
3
4
5
6
7
8
9
10
11
/// 请求报文格式
<method>空格<request-url>空格<version>
<headers>
空行
<entity-body>

/// 响应报文格式
<version>空格<status>空格<reason-phrase>
<headers>
空行
<entity-body>

各部分的作用如下:

  • 起始行和首部是由行分割的 ASCII 文本,每行由一个回车符(\n)和一个换行符(\r)组成的序列结束。这个序列可以写作CRLF
  • method,客户端希望服务器执行的动作。
  • request-url,请求的资源路径。
  • version ,HTTP 的版本,如HTTP/1.0。不同版本有不同的特性。
  • status,3 位数,描述了请求过程中的情况。具体介绍在后面。
  • reason-phrase,和status对应,是其描述。
  • headers ,可以没有或多个。具体介绍在后面。
  • entity-body,数据块,主体是可选的,可以为二进制或文本。

下面我们再了解下方法、状态码和首部的内容。

方法

HTTP 方法列表:

HTTP 方法 描述
GET 告知服务器,需要从服务器向客户端发送命名资源
HEAD 仅发送命名资源响应中的 HTTP 首部
PUT 将客户端的数据存储的命名的服务器资源中
POST 将客户端数据发送到一个服务器应用程序
TRACE 追溯一个请求
OPTIONS 查看服务器对资源支持的操作
DELETE 从服务器删除资源

虽然 HTTP 规定了这些方法,具体服务器是否支持,由服务器确定。

  • GET,从服务器获取资源,HTTP/1.1 要求实现的方法。
  • HEAD,和GET方法类似,但是响应报文中不会包含主体部分。使用该特性,可以在不真正获取资源的情况下完成:
    • 判断资源类型
    • 查看对应资源是否存在
    • 查看资源是否被修改 HTTP/1.1 规范中要求实现该方法,并且对于同一资源,该方法响应首部应该和GET方法返回的相同。
  • PUT,和GET相反,请求服务器在指定位置创建文件,内容为请求主体的内容。若对应资源存在,则替换。
  • POST,客户端向服务器发送数据。常用来提交表单。
  • TRACE,客户端发出请求后,可能经过中间的网关、代理等,原始请求可能被修改,使用TRACE可以查看最终到达服务器的请求具体是什么样子(服务器在响应报文的主体中包含其收到的请求报文)。下面是一个示例:

    TRACE通常用于诊断一个请求是否能到达服务器,不能带有主体部分。

  • OPTIONS,用于查看服务器对特定资源所支持的方法。在请求报文中若使用*代替 URL,则意为查看服务器对所有资源的通用方法。
  • DELETE,请求服务器删除指定资源。当然,具体是否删除,由服务器决定。

HTTP 扩展方法

HTTP扩展方法指的是没有在 HTTP 规范中定义的方法。例如,下面是在WebDAV HTTP扩展中的方法:

扩展方法名 描述
LOCK 告知服务器,对指定资源锁定,防止其他人对其更改
MKCOL 允许用户创建资源
COPY 允许用户 复制资源
MOVE 移动服务器资源

状态码

100~199 信息性状态码

这些状态码较新,在 HTTP/1.1 引入。下面是已定义的状态码:

Code 原因短语 描述
100 Continue 服务器收到请求的初始部分,请客户端继续。
101 Switching Protocols 服务器正在根据客户端的指定,将协议更换成 Update 首部所列协议。

对于状态码 100,起初的设计是为了:客户端想发送一个实体到服务器,但在发送之前想查看服务器是否愿意接受。需要知道的是:

  • 对于客户端,若客户端希望发送一个实体,并且愿意等待服务器状态码为 100 的响应,那么客户端的请求报文中应包含值为100 ContinueExpect首部。客户端在发送请求后,不要一直等待,可以在超出一定时间后直接发送实体。
  • 对于服务器,若服务器收到包含值为100 Continue的首部,应该以100 Continue或其他对应错误状态码响应。服务器不应该向没有包含100 Continue首部的请求响应100 Continue状态码。若服务器在响应100 Continue状态之前已经收到客户端发送的实体部分,可以跳过响应100 Continue,但要响应最终的状态。
  • 对于代理,若代理接受到客户端包含100 Continue的请求,在代理知道请求的下一跳只支持 HTTP/1.0(或更早),它应该响应417 Expectation Failed;在代理知道下一跳支持 HTTP/1.1 或没有清楚的状态,则应转发这一请求。若代理将上游服务器响应转发给客户端时,知道客户端不支持 HTTP/1.1,则不应响应100 Continue

200~299 成功状态码

在请求成功时,服务器会返回代表成功的状态码;对于不同的请求方法,状态码有可能会有区别。已知的成功状态码如下:

Code 原因短语 描述
200 OK 最常见。请求成功,响应主体包含了具体的数据。
201 Created 响应在服务器 创建资源的请求,如 PUT。服务器应确保资源被创建,并在响应报文中包含资源 URL。
202 Accepted 服务器以接收到请求,但还未执行任何操作。
203 Non-Authoritative Information 实体首部(也可以称为元信息)包含的信息不是来自于服务器,而是资源的一个副本。若中间节点上有一份资源副本,但无法或没有对它发出的与资源有关的元信息进行验证,就会出现这种情况。当然,这种状态并不是非用不可,若实体首部来自服务器,返回 200 完全可以。
204 No Content 响应报文中无主体部分。主要用于在浏览器不转为显示新文档情况下,对其更新。
205 Reset Content 负责告知浏览器清除当前页面中所有 HTML 元素。
206 Partial Content 成功执行一个部分或 Range 请求。客户端可以在首部中指定请求某个范围内的文件。该状态响应头部必须包含 Content-Range、Date、以及 ETag 或 Content-Location。

300~399 重定向状态码

已知状态码列表:

Code 原因短语 描述
300 Multiple Choices 客户端请求实际指向多个资源的 URL。客户端可以在响应中找到资源列表。
301 Moved Permanently 请求的 URL 已被移除。响应的 Location 首部包含现在所处的位置。
302 Found 与 301 类似,客户端本次应使用响应中的临时 URL,将来的请求任使用以前的 URL。
303 See Other 告知客户端使用另一个 URL 来获取资源。其主要目的是,允许 POST 请求的响应将客户端定向的某一个资源上去。
304 Not Modified 若客户端发起一个有条件的 GET 请求,而资源未被修改,可以使用该状态码说明资源未被修改。
305 Use Proxy 必须通过代理来访问这一资源,代理有 Location 首部给出。需要知道的是,客户端接收到这一状态时,不应该假定所有请求都经过代理。
306 未使用 暂未使用。
307 Temporary Redirect 和 302 相同。

对于302303307状态码的说明:从上面表格上看,这 3 个状态码出现交叉的情况;在 HTTP/1.0,只有302,服务器希望对 POST 请求响应302后,客户端向从定向的 URL 发送 GET 请求。303307是在 HTTP/1.1 加入,303时,浏览器依然执行 HTTP/1.0 302的动作;307,只是不会将原始的 POST 转为 GET,而是询问用户。这些都是规范说辞,但实际运用中不是这么回事,你有看到大量的307

400~499 客户端错误状态码

有时客户端发送服务器无法处理的东西,会导致错误。 已知状态码列表:

Code 原因短语 描述
400 Bad Request 告知客户端它发送了一个错误的请求。
401 Unauthorized 与适当首部一同返回,告知客户端在请求之前先进行认证。
402 Payment Required 保留未使用。
403 Forbidden 请求被拒绝。
404 Not Found 服务器无法找到请求的 URL。
405 Method Not Allowed 客户端使用不支持的方法请求 URL。应该在首部使用 Allow 告知客户端正确的方法。
406 Not Acceptable 客户端在使用指定参数说明其愿意接收什么类型的实体,但服务器没有与之对应的资源。
407 Proxy Authentication Required 代理服务器要求客户端验证。
408 Request Timeout 客户端完成请求时间过长,服务器可以关闭链接。
409 Conflict 服务器认为该请求可能引起冲突。响应主体中应包含冲突的主体的描述。
410 Gone 与 404 类似,只是服务器曾经拥有此资源,后来被移除。
411 Length Required 服务器要求请求报文中包含 Content-Length 首部。
412 Precondition Failed 客户端发起条件请求,其中有条件失败。
413 Request Entity Too Large 客户端发送的主体部分比服务器能够活希望处理的要大。
414 Request URI Too Long URL 过长。
415 Unsupported Media Type 服务器无法理解或无法支持客户端发送的内容类型。
416 Requested Range Not Satisfiable 请求范围无效或无法满足。
417 Expectation Failed 请求首部包含 Expect 期望,但服务器无法满足。

500~599 服务器错误状态码

客户端发送的是有效请求,服务器自身出错。下面是已知状态码列表:

Code 原因短语 描述
500 Internal Server Error 服务器遇到一个妨碍它提供服务的错误。
501 Not Implemented 客户端发起的请求超出服务器能力范围,如使用了不支持的方法。
502 Bad Gateway 无效网关。通常不是这上游服务器关闭,而是使用了上游服务器不同意协议交换数据。
503 Service Unavailable 服务器暂时无法提供服务。若服务器知道服务什么时间可以使用,可以在响应头中加入 Retry-After 首部说明。
504 Gateway Timeout 于 408 类似,只是这里的响应来自一个网关或代理,它们在等待另一个服务器响应对其请求响应时超时。
505 HTTP Version Not Support 服务器收到的请求使用了它无法支持的协议版本。

首部

首部和方法的配合,共同决定了客户端和服务器能够做什么样的事情。 首部的类型分为:

  • 通用首部,请求报文和响应报文都可以使用。包括但不仅限于:

    首部 描述
    Connection 客户端和服务器指定链接有关选项
    Date 日期时间标志,说明报文是什么时间创建的
    MIME-Version 发送端使用的 MIME 版本
    Trailer 若报文采取分块传输编码方式,可以使用该首部列出位于报文拖挂部分的首部集合。
    Transfer-Encoding 告知接收方为了保证报文的可靠传输,对报文采用了什么编码方式。
    Update 发送端可能想要升级使用的新版本或协议
    Via 报文经过的中间节点
    Cache-Control 缓存指示
  • 请求首部,只在请求报文中有意义,说明了客户端的情况。包括但不仅限于:

    首部 描述
    Client-IP 客户端 IP 地址
    From 客户端用户 E-mail 地址
    Host 接收请求的服务器主机名和端口号
    Referer 包含当前请求 URI 的文档的 URL。就是说当前请求 URL 所在的那个页面对应的 URL。
    User-Agent 发起请求的应用程序信息
    UA-Color、UA-CPU、UA-Disp、UA-OS、UA-Pixels 分别代表客户端显示器颜色信息、CPU 信息、显示器信息、操作系统信息、显示器像素信息
    Accept、Accept-Charset、Accept-Encoding、Accept-Language、TE 分别表示客户端可接受的媒体类型、字符集、编码方式、语言以及扩展编码
    Expect 允许客户端列出要求服务器的行为
    If-Match 若实体标记与文档当前实体标记匹配,就获取这份文档
    If-None-Match 若实体标记与文档当前实体标记不匹配,就获取这份文档
    If-Modified-Since 除非在指定日期之后资源被修改过,否则就限制这个请求
    If-Unmodified-Since 除非在指定日期之后资源没有被修改过,否则就限制这个请求
    If-Range 对文档某范围进行条件请求
    Range 请求指定范围内的资源
    Authorization 客户端提供给服务器以便进行认证的数据
    Cookie 客户端向服务器发送的令牌
    Cookie2 说明客户端支持的 cookie 版本
    Max-Forward 和 TRACE 方法一同使用,控制请求转发的最大次数
    Proxy-Authorization 和代理进行认证是使用
    Proxy-Connect 和代理建立链接时控制链接
  • 响应首部,为客户端提供了额外信息,使得客户端可以做出更好的响应。包括但不仅限于:

    首部 描述
    Age 从最初创建开始,响应持续时间
    Public 服务器为其资源支持的请求方法列表
    Retry-After 若资源不可用,在此日期之后重试
    Server 服务器应用软件信息
    Title HTML 文档的标题
    Warning 比原因短语更详细的警告报文
    Accept-Ranges 服务器可以接收的范围类型
    Vary 缓存信息
    Proxy-Authenticate 代理对客户端的质询列表
    Set-Cookie 服务器在客户端设置的令牌
    WWW-Authenticate 服务器对客户端的质询列表
  • 实体首部,描述实体相关信息。包括但不仅限于:

    首部 描述
    Allow 对此实体支持的请求方法
    Location 告知客户端资源的实际位置
    Content-Base、Content-Encoding、Content-Language、Content-Length、Content-Location、Content-MD5、Content-Range、Content-Type 分别表示主体的基础 URL、编码方式、使用语言、长度或尺寸、实际位置、MD5 校验和、在整个范围中该实体的字节范围、对象类型
    BTag 实体标记
    Expires 实体不再有效
    Last-Modified 最后一次被修改的日期

结语

该篇主要是扩大眼界,不必死记硬背。我们下篇见.祝大家有个开心的周末!