Message of HTTP
HTTP
(HyperText Transfer Protocol) is a stateless(无状态)
application-level request/response
protocol that uses extensible semantics(可扩展语义) and self-descriptive(自描述) message payloads for flexible interaction with network-based hypertext information systems. - from RTC7230。
HTTP
是一种能够获取HTML这样的网络资源的通讯协议。是web上进行数据交换的基础,是一种client-server
协议。
HTTP
是应用层的协议,通过TCP或者TLS(加密的TCP)连接来发送信息,不仅用来传输超文本文档,也可以传输图片、视频,也可以部分文档内容更新网页。
996年,HTTP的下一个版本,即HTTP/1.0的演变比原始版本有了很大的改进。
与仅为HTML响应设计的HTTP/0.9不同,HTTP/1.0现在可以处理其他响应格式,即图像、视频文件、纯文本或任何其他内容类型。它添加了更多方法(即POST和HEAD),更改了请求/响应格式,将HTTP标头添加到请求和响应中,添加了状态代码以识别响应,引入了字符集支持,包括多部分类型、授权、缓存、内容编码等。
以下是示例HTTP/1.0请求和响应的样子:
GET / HTTP/1.0
Host: cs.fyi
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
Accept: */*
如您所见,除了请求外,客户还发送了其个人信息、所需的响应类型等。虽然在HTTP/0.9中,客户端永远无法发送此类信息,因为没有headers。
对上述请求的示例响应可能如下所示
报文
报文主要是在客户端和服务端之间进行流通。Client发送的报文称为请求报文,服务端返回给Client的称之为响应报文。
报文是数据传输的载体,互联网上所有展示的信息以及服务器流通的数据都是报文。
报文组成
Client发送一个HTTP请求向服务端,这个请求以一个请求行(request-line)开始,包含了Method、Path、Protocol Version;接下来是请求修饰符(request modifiers),包含了客户端信息以及表示元数据的头字段;最后就是包含有效负载的消息正文。
报文语法
HTTP-message = start-line*(header-field CRLF)CRLF[ message-body ]
起始行以及头部
起始行(start-line)包含了请求行(request-line)和响应行(status-line)。
起始行包含了客户端请求的一些方法
请求方法
Method | description | 是否包含主体 |
---|---|---|
GET | 从服务器获取一份文档 | no |
HEAD | 只从服务器获取文档的首部 | no |
POST | 向服务器发送要处理的数据 | yes |
PUT | 将请求的主体部分存储在服务器上 | yes |
DELETE | 从服务器上删除一份文档 | no |
OPTIONS | 决定在服务器上可以执行哪些方法 | no |
TRACE | 对可能经过代理服务器传送到服务器上的报文进行追踪 | no |
响应行也就是服务端反馈给客户端状态信息,也就是状态码以及响应短语。
首部
Header Field 包含了一个不区分大小写的 Field Name
后面跟 ":"
以及 Field Value。
所有的消息头都在IANA注册表中列出,原始内容在 RFC4229 定义。
Header-field = field-name ":" OWS field-value OWSOWS = Optional whiteSpace
首部和方法共同决定了客户端和服务器要做什么。首部主要分为四个类型。
- 通用首部
- 请求首部
- 响应首部
- 实体首部
通用首部
通用首部是客户端和服务器都可以使用的,提供了与报文相关的基础功能。在客户端和服务器都提供一些通用的功能,比如 **Date,每一端都可以用它来构建报文的时间。**通用首部只能在请求头部或者响应头部,不能在实体头部。
header | description |
---|---|
Connection | 允许客户端和服务器指定请求或者响应是否连接选项 |
Date | 报文创建的时间 |
Cache-Control | 随报文传递是否缓存指示 |
Transfer-Encoding | 告知接收端为了传输安全,报文采用什么编码方式 |
Trailer | 实现报文主体后记录哪些首部字段,该首部字段可以使用在HTTP/1.1版本分块传输编码时。 Trailer: Expiress |
Upgrade | 要求服务器升级到一个高版本协议 |
Via | 告诉服务器,这个请求是哪些代理发出去的 |
Connection
Connection header 决定当前事务(请求/响应)结束后,是否关闭网络连接。如果其值是Keep-alive,网络连接就是持久性的。这样同一个服务器上的请求都可以在这个连接上完成。
Connection: keep-alive // 持久连接 http/1.1 的默认值Connection: close // 关闭网络连接 http/1.0 的默认值
Date
Date 包含了报文创建的时间和日期
Date: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT// GMT 格林尼治时间 不是本地时间// Date: Wed, 21 Oct 2020 08:29:33
Cache-Control
Cache-Control 被用于请求和响应中,通过指定来实现缓存机制。缓存是单向的,请求中设置了,只在请求中有效。
缓存指令
// 客户端缓存指令Cache-Control: max-age=<second> // 设置缓存的最大周期,单位SCache-Control: max-stale[=<second>] // 客户端可以接受过期的资源Cache-Control: no-cache // 发布缓存副本之前,强制要求把请求交给原始服务器进行验证(协商缓存)Cache-Control: no-store // 不使用任何缓存,缓存不应该存储有关客户端或者服务器响应的任何内容Cache-Control: no-transform // 不得对资源进行转换或者转变// 服务器缓存指令Cache-Control: public // 响应可以被任何对象缓存Cache-Control: private // 响应只能被单个用户缓存
有关Cache-Control的其他指令,可以查询[RFC7234] 或者 [MDN Cache-Control]
Transfer-Encoding
Transfer-Encoding 指明将消息实体传递给用户所采用的的编码方式。一般出现在响应头部。仅用于两个节点之间消息传输,如果是端到端之间的传输,采用Content-Encoding
Transfer-Encoding: chunked // 数据以分块的方式发送Transfer-Encoding: compress // 采用Lempel-Ziv-Weich压缩算法Transfer-Encoding: gzip // 采用Lempel-Ziv coding 压缩算法// e.gTransfer-Encoding: gzip, chunked
有关Transfer-Encoding 其他的描述以及指令,可以查询[RFC7230] 或者 [MDN Transfer-Encoding]
请求首部
请求首部主要是针对请求报文中有意义的首部。服务器可以根据客户端请求报文中提供的首部进行更好的响应。
请求首部根据不同功能也分为以下类型
信息型首部
信息型首部主要是提供的当前请求报文的载体(客户端)的信息
Header | description |
---|---|
Client-IP | 客户端机器的IP地址 |
From | 提供了客户端中用户的E-Mail地址 |
Host | 提供了请求服务器的主机地址以及端口号(无 默认 HTTPS 443 HTTP 80) |
Referer | 包含了当前请求URL的来源页面的地址 |
User-Agent | 将发起请求的客户端的名称告知服务器 用户代理 |
Referer 首部
此请求头表示了该页面是从来源页面的链接进入的,因此,使用Referer
头可以记录到用户浏览信息,可以用来统计分析、日志分析以及缓存优化等。
下面两种情况 referer
是不会发送的
- 来源页面采用的协议表示本地的
“file”
或者“data"
URL - 当前请求页面采用的是HTTP,来源页面采用的是安全协议
Accept 类型首部
Accept header 主要是告知服务器 客户端可以处理什么类型的内容。内容类型用MIME类型(媒体类型)表示。服务器在响应头 Content-type 应答客户端。
Header | Description |
---|---|
Accept | 告知服务器可以接受的媒体类型 |
Accept-Charset | 告知服务器可以处理的字符集 |
Accept-Encoding | 告知服务器能够发送哪些编码 |
Accept-Language | 告知服务器能够发送哪些语言 |
客户端为请求加上某些限制时,使用条件型首部。
Header | Description |
---|---|
Expect | 允许客户端列出某请求的所要求的服务器行为 |
If-Match | 实体标记和文档当前的实体标记相匹配,获取文档 |
If-None-Match | 实体标记和文档当前的实体标记不相匹配,获取文档 |
If-Modified-Since | 某个资源在指定日期之后修改过,则返回对应资源 |
If-Unmodified-Since | 某个资源在指定日期之后没有修改过,则返回对应资源 |
If-Range | 允许对文档的某个范围内进行请求 |
安全型首部
在客户端获取特定的响应资源时,会先对自身进行验证。这个也叫HTTP一种安全机制 质询/响应认证
Header | Description |
---|---|
Authorization | 客户端提供给服务端的自身数据进行验证 |
Cookie | 客户端向服务器提供一个令牌 |
Cookie Header
代理型首部
代理型的首部目前有 Proxy-Authenticate
、Proxy-Authentication-Info
、Proxy-Authorization
、Proxy-Features
、Proxy-Connection
。
响应首部
响应首部也有其对应的功能,比如谁在发送请求,发送给客户端的信息应该如何处理。
信息型首部
Header | Description |
---|---|
Age | 最初创建开始 响应持续的时间 |
Server | 服务器应用程序的软件的名称和版本 |
协商首部
对资源有多种的表示方法。
协商首部有 Accept-Ranges
、 Vary
,ETag
,后面对协商首部会有详述。
Header | Description |
---|---|
Accept-Ranges | 是否接收字节范围请求 |
Vary | 代理服务器缓存的管理信息 |
ETag | 资源的匹配信息 |
安全首部
安全首部跟请求首部类似
实体首部
实体首部提供了大量跟消息和其内容有关的信息。告知报文的接收者对消息进行什么操作。
信息首部
Header | Description |
---|---|
Allow | 可以对实体执行的请求方法 |
Location | 告知客户端实体实际的位置,将接收端定位到定向到资源的URL |
内容首部
该首部提供了与实体内容有关的信息
Header | Description |
---|---|
Content-Encoding | 对主体内容执行的编码方式 |
Content-Language | 主体内容使用的语言 |
Content-Length | 主体内容的长度 |
Content-Location | 主体内容的实际位置 |
Content-MD5 | 主体内容的MD5校验 |
Content-Range | 整个资源中该主体内容的表示的字节范围 |
Content-Type | 主体的媒体类型 |
缓存首部
通用的缓存首部说明如何、什么时候缓存。实体首部缓存提供了与被缓存实体有关的信息。
Header | Description |
---|---|
ETag | 与当前实体有关的标记 |
Expires | 实体不再有效 |
Last-Modified | 当前实体最后一次修改的时间 |
状态码
- [100 - 199]
信息提示
请求已接收,继续进程进程,已定义范围 100 - 101
code | reason-phrase | description |
---|---|---|
100 | Continue | 收到了请求的初始部分,请客户端继续。更多请看[RFC 7231 6.2.1] |
101 | Switching Protocols | 服务器根据客户端指定,将协议切换成Update首部所列协议更多请看[RFC 7231 6.2.2] |
- [200 - 299]
成功
请求被成功接收、理解以及处理,已定义范围 200 - 206
code | reason-phrase | description |
---|---|---|
200 | OK | 请求无问题 |
201 | Create | 用户创建服务器对象的请求 |
202 | Accepted | 请求已被接受,但是还没有处理 |
203 | Non-Authoritative Information | 实体首部包含信息不是来源于源服务器 |
204 | No Content | 没有实体主体部分 |
205 | Reset Content | 另一个主要用于浏览器代码 |
206 | Partial Content | 成功执行了一个部分或者range范围请求 |
- [300 - 399]
重定向
需要进一步采取行动 以便完成请求,已定义范围 300 - 305
重定向一般是服务器告知客户端需要进一步去请求资源移动到新服务器。如果资源被移动了,服务器响应重定向状态码以及一个新的资源地址,一边客户端去请求所需资源信息。
重定向还可以识别资源是否被修改过。客户端请求头加了 **If-Modifier-Since,**如果在这个时间之后没有修改文档,则不会返回响应,直接返回状态码。
// 请求报文POST /test HTTP/1.1Host: www.nate.comIf-Modifier-Since: Tue Dec 01 2010 16:27:22 GMT// 响应报文HTTP/1.1 304 Not Modifier
code | reason-phrase | description |
---|---|---|
300 | Multiple Choices | 客户端请求一个实际指向多个资源的URL会返回 |
301 | Move Permanently | 在请求的URL已被移除时使用 |
302 | Found | 客户端使用Location首部给出的URL来定位资源 |
303 | See Other | 告知客户端使用另一个URL获取资源 |
304 | Not Modified | 告知客户端资源是否被修改过 |
305 | Use Proxy | 必须通过一个代理来访问资源,代理位置由Location给出 |
- [400 - 499]
客户端错误
请求包含错误语法,已定义范围 400 - 415
客户端错误码也是常见的,比如常见的400、404
code | reason-phrase | description |
---|---|---|
400 | Bad Request | 告知客户端发送了一个错误的请求 |
401 | Unauthorized | 由于缺少有效的身份验证,必须传送WWW-Authenticate标头 |
402 | Payment Required | 未使用 |
403 | Forbidden | 请求被服务器拒绝了 |
404 | Not Found | 请求URL未被服务器找到 |
405 | Method Not Allowed | 请求中方法服务器不支持 |
406 | Not AcceptTable | 服务器没有匹配到客户端所要求类型的实体 |
407 | Proxy Unauthorized Required | 用于对资源需要认证的代理服务器 |
408 | Request Timeout | 客户端请求耗时太长 |
409 | Conflict | 在资源上引发一些冲突 |
410 | Gone | 类似404,服务器曾经拥有过资源 |
411 | Length Required | 服务器要求请求报文中包含Content-Length头 |
412 | Precondition Failed | 客户端发起的条件请求,其中一个失败了 |
413 | Payload Too Large | 客户端发起的请求实体主体比服务器所能处理还要大 |
414 | Request URL Too Long | 请求URL太长了 |
415 | Unsupported Media Type | 服务器无法理解请求媒体类型 |
416 | Requested Range Not Satisfiable | 请求报文所请求的是指定资源的范围 |
417 | Expectation Failed | 请求头Except包含了一个期望,服务器无法理解 |
- [500 - 599]
服务器错误
,服务器错误执行了请求,已定义范围 500 - 505
code | Reason Phrase | Description |
---|---|---|
500 | Internal Server Error | 服务器错误 |
501 | Not Implemented | 客户端发起的请求超出了服务器能力范围 |
502 | Bad Gateway | 作为代理或网关使用的服务器从请求响应链的下一条链路上收到了伪响应 |
503 | Service Unavailable | 服务器无法为请求提供服务 |
504 | Gateway Timeout | 响应来自网关或者代理,等待另一服务器请求超时了 |
505 | HTTP Version Not Supported | 服务器收到的请求使用其无法理解的协议版本 |
更多有关状态码的信息可以查询 [RFC7231]规范