HTTP
快速参考|
245
消息
HTTP
消息指客户端发给服务器的请求,或者服务器发给客户端的响应。
请求和响应都有一个起始行、零个或多个首部字段、表示首部字段结束的一个空行(即
一行中只有
CRLF
),此外可能还有包含消息载荷(
payload
)的主体。这个格式如下:
start-line
*(message headers CRLF)
CRLF
[ message-body ]
首部字段包含一般的首部、请求首部、响应首部和实体首部。
消息主体(如果有的话)是请求或响应对应的
HTTP
消息的实体主体。实体主体可能使
Transfer-Encoding
字段指定的方式编码。此时,它与消息主体有所不同:
message-body = entity-body
| <entity-body as encoded per Transfer-Encoding>
RFC 2616
4
节(
https://tools.ietf.org/html/rfc2616#section-4
)对
HTTP
消息做了
深入说明。
虽然请求和响应消息使用通用的格式传输消息载荷,但是二者之间的句法有些区别。
请求消息
HTTP
请求始终由客户端发给服务器。消息的第一行包括请求方法、资源标识符(
URI
HTTP
协议版本。
HTTP
定义了几个常用的方法。此外,资源可以在
Allow
首部字段中指定允许使用的方法。
请求消息使用特定的方法请求资源时,响应消息返回的代码会告知客户端是否允许或实
现了那个方法。
如果服务器实现了那个方法,但是不允许使用它请求资源,源服务器应该返回
405
(不
允许使用的方法)状态码。如果未能识别方法或者未实现方法,应该返回
501
(未实现)
稍后会说明状态码。
客户端可以通过请求首部把额外的信息发给源服务器。请求首部字段的作用相当于修饰
语,语义与编程语言中方法调用的参数一样。
246
附录
A
完整的
HTTP
核心方法如下:
Method = "OPTIONS" ;
| "GET" ;
| "HEAD" ;
| "POST" ;
| "PUT" ;
| "DELETE" ;
| "TRACE" ;
| "CONNECT" ;
| extension-method
| extension-method = token
部分方法的详情,以及与
Rails
控制器动作的对应关系,参阅第
4
的“
HTTP
语义”一节
HTTP
方法在
RFC 2616
9
节定义
https://tools.ietf.org/html/
rfc2616#section-9
)。
响应消息
源服务器收到请求消息,经过解释后,会发回
HTTP
响应消息。
响应消息的第一行是状态,包含
HTTP
协议版本、状态码数字和对应的文本描述:
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
状态码是服务器解析和解释请求之后得出的标识符,由三个数字组成。状态码的作用是
让客户端软件理解服务器的回应。文本描述是对状态码的解释,人类可读,客户端无需
查看或显示。
状态行之后是响应首部。服务器可以在响应首部中发送关于自身的额外信息和所请求资
源的信息。
实体
请求消息和响应消息都可以包含一个实体。实体由实体首部和实体主体组成。
实体首部定义与实体主体或所请求资源有关的元信息。根据
HTTP
协议规范,其中有些
信息是可选的,而有些则是必须的。
有消息主体时才能有实体主体。如果有实体主体,它的数据类型由
Content-Type
Content-Encoding
字段决定。
实体主体是有序的两层结构:
HTTP
快速参考|
247
entity-body := Content-Encoding( Content-Type( data ) )
Content-Type
字段指定所含数据的媒体类型,
Content-Encoding
字段指定数据内容的编
码(例如,是否压缩数据)。
HTTP
协议没有定义默认的编码。
连接
HTTP
支持在一个
TCP
连接中发送和接收多个
HTTP
请求
/
响应消息。这叫持久连接、
保活或连接重用。根据
HTTP 1.0
,如果客户端支持
Keep-Alive
首部字段,应该将其添
加到请求中:
Connection: Keep-Alive
服务器处理请求时,也会把这个首部字段添加到响应中。这样,连接保持打开状态,传
输后续消息。如果客户端再次发送请求,会使用同一个
TCP
连接。仅当客户端或服务器
丢弃连接,连接才会中断,表明通信结束。
HTTP 1.1
中,除非明确指定,所有连接都是持久的。
HTTP 1.1
还实现了短连接超时,
以便源服务器快速传送一个网页的多个部分,而不消耗过多的资源。
支持持久连接的客户端可能还会以流水线的方式发送请求,即不等待各个响应,直接发
送多个请求。源服务器会按照收到请求的顺序做出响应。
状态码定义
状态码是三个数字,定义服务器对请求的响应状态。第一个数字是响应的类型。
HTTP
定义了五种响应类型:
1xx: Informational - Request received, continuing process
2xx: Success - The action was successfully received,
understood, and accepted
3xx: Redirection - Further action must be taken in order to
complete the request
4xx: Client Error - The request contains bad syntax or cannot
be fulfilled
5xx: Server Error - The server failed to fulfill an apparently
valid request
HTTP 1.1
还定义了各个状态码的值,即原因短语,推荐各个应用使用(也可以不用,对
HTTP
协议没有影响)。最常用的状态码有:
Status-Code = 100 : Continue
| 200: OK
| 201: Created
| 202: Accepted
248
附录
A
| 204: No Content
| 301: Moved Permanently
| 302: Found
| 303: See Other
| 304: Not Modified
| 400: Bad Request
| 401: Unauthorized
| 403: Forbidden
| 404: Not Found
| 500: Internal Server Error
| 501: Not Implemented
| 502: Bad Gateway
| 503: Service Unavailable
HTTP
状态码在
RFC 2616
10
节定义
https://tools.ietf.org/html/rfc2616#section-
10
)。
访问验证
HTTP
提供了多种可选的质询-响应验证机制,服务器可以使用这些机制质询客户端请
求,客户端可以使用这些机制提供身份验证信息。
这些机制在
RFC 2617
中定义(
https://tools.ietf.org/html/rfc2617
),与
HTTP
协议是分
开的。不过要注意,
HTTP
提供的身份验证方案不是安全的用户身份验证方法,除非结
合其他安全的方法,例如
SSL
内容协商
内容协商指给定响应有多种表述时从中选择一种表述。响应的表述可以在类型、语言、
编码等方面不同。
HTTP
定义了两种内容协商方法:服务器驱动和代理驱动。这两种方
法是正交的,因此可以单独使用,也可以结合使用。透明协商是一种结合使用,协商工
作由缓存接手。
支持的内容协商方式参见
RFC 2616
12
节(
https://www.w3.org/Protocols/rfc2616/
rfc2616-sec12.html#sec12
)。
缓存
HTTP
是为分布式信息系统设计的,使用缓存能提升性能。因此,为了尽量高效地利用
响应缓存,协议中定义了几种方法和元素。
HTTP
快速参考|
249
HTTP
中,缓存的最终目的是尽量减少发送请求或响应的必要,从而减少网络回路次
数和通信占用的网络带宽。
缓存是
HTTP
REST
的重要组成部分。在
REST
式架构中,最高效的网络请求是不使
用网络的请求,转而依靠缓存。
为了定义缓存能力,
HTTP
引入了语义透明度(
semantic transparency
)概念。如果缓存
对客户端和源服务器都没有影响,只是提高了性能,那么就说这种缓存方法是语义透明
的。也就是说,如果缓存方法是语义透明的,那么客户端从缓存中收到的响应与从源服
务器中收到的一模一样。
HTTP 1.1
允许客户端、服务器和缓存方法在提升性能时显著降低语义透明度。
HTTP
还定义了缓存正确性(
cache correctness
),指明缓存或缓存方法要尽量发送最新
的响应。
如果缓存返回的响应不是最新的或者不够新,要在响应中添加
Warning
首部,好让客户
端正确地处理。
12
章详细讨论了客户端和服务器缓存,以及缓存控制机制,那一章还说明了把外部资
源集成到自己的应用中的最佳方式。
安全注意事项
HTTP
客户端和服务器经常交互大量用户生成的数据,因此处理数据时要小心,以防通
HTTP
协议泄露到外部。
16
章讨论了开发者要面对的一些安全挑战,但是这里我们还要重申几个关键点。
服务器处理用户发送的请求时可能会记录个人数据,而且比预想的要多,潜在的攻击者
可以通过多种方式使用这些数据。用户的想法、操作、品味和偏好往往会泄露出去,要
么是通过请求消息间接泄露,要么是通过在网上发布信息主动披露。
此外还要注意,用户在网上的交互越来越复杂,而且能分享的文件类型越来越多,他们
通常不知道也没有权衡分享了什么信息,可能觉得只是在做一件平常的事。
因此,应用开发者要担起责任,实现一定的方式方法去保护用户的隐私,防止用户数据
意外泄露和未经授权访问。

Get RESTful Rails Development (中文版) now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.