Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content
1. Introduction
HTTP (超文本传输协议) 是一种无状态的应用层协议,主要用于分布式、协作式的超文本信息系统。每个 HTTP 消息要么是请求,要么是响应。服务器监听连接上的请求,解析每条接收到的消息,解释消息语义,并根据请求目标做出响应。客户端构建请求消息以传达特定意图,并检查接收到的响应以确定意图是否实现。
HTTP 提供了一个统一的接口用于与资源交互(第 2 节),无论其类型、性质或实现方式如何,都是通过表示的操作和传输(第 3 节)来实现的。
HTTP 语义包括每个请求方法定义的意图(第 4 节),请求头字段(第 5 节)可能描述的语义扩展,用于指示机器可读响应的状态码(第 6 节),以及响应头字段中可能给出的其他控制数据和资源元数据的意义(第 7 节)。
2. Resources
HTTP 请求的目标称为"资源"。HTTP 不限制资源的性质;它仅定义了一个接口,用于与资源交互。每个资源由一个统一资源标识符(URI)标识。
3. Representations
考虑到资源可以是任何东西,HTTP 提供了一个统一的接口,通过消息通信来观察和操作这些东西,这需要一个抽象来表示通信中的当前或期望状态,这个抽象称为表示。
3.1. Representation Metadata
表示头字段提供表示的元数据。当消息包含一个有效负载体时,表示头字段描述如何解释有效负载体中的表示数据。以下头字段传达表示元数据:
- Content-Type
- Content-Encoding
- Content-Language
- Content-Location
3.2. Representation Data
表示数据与 HTTP 消息相关联,通常作为消息的有效负载体提供,格式和编码由表示元数据头字段定义。
3.3. Payload Semantics
一些 HTTP 消息传输完整或部分表示作为消息的"有效负载"。有效负载的目的由方法语义定义。例如,PUT 请求的有效负载表示目标资源的期望状态。
3.4. Content Negotiation
HTTP 提供了内容协商机制,以便服务器根据用户代理的偏好选择最佳表示。内容协商有两种模式:主动协商和被动协商。
4. Request Methods
请求方法是请求语义的主要来源,指示客户端发出请求的目的及期望的成功结果。
4.1. Overview
HTTP 定义了一些标准化的方法,如下表所示:
- GET
- HEAD
- POST
- PUT
- DELETE
- CONNECT
- OPTIONS
- TRACE
所有通用服务器必须支持 GET 和 HEAD 方法,其他方法是可选的。
4.2. Common Method Properties
4.2.1. Safe Methods
如果请求方法的定义语义本质上是只读的,则认为该方法是"安全的"。GET、HEAD、OPTIONS 和 TRACE 方法被定义为安全的。
4.2.2. Idempotent Methods
如果多次相同请求方法对服务器的预期效果与单次请求相同,则认为该方法是"幂等的"。PUT、DELETE 和所有安全方法都是幂等的。
4.2.3. Cacheable Methods
请求方法可以定义为"可缓存的",以指示响应可以被存储以供将来重用。GET、HEAD 和 POST 方法被定义为可缓存的。
4.3. Method Definitions
4.3.1. GET
GET 方法请求传输目标资源的当前表示。GET 是信息检索的主要机制。
4.3.2. HEAD
HEAD 方法与 GET 相同,但服务器在响应中不发送消息体。
4.3.3. POST
POST 方法请求目标资源处理请求中包含的表示。
4.3.4. PUT
PUT 方法请求用请求消息有效负载中的状态创建或替换目标资源的状态。
4.3.5. DELETE
DELETE 方法请求服务器删除目标资源的当前表示。
4.3.6. CONNECT
CONNECT 方法请求建立到目标资源标识的服务器的隧道。
4.3.7. OPTIONS
OPTIONS 方法请求目标资源的通信选项。
4.3.8. TRACE
TRACE 方法请求远程应用级别的回送请求消息。
5. Request Header Fields
客户端发送请求头字段以提供有关请求上下文的更多信息。
5.1. Controls
控制字段是指示请求特定处理的请求头字段。
5.1.1. Expect
Expect 头字段在请求中指示需要服务器支持的一组行为。
5.1.2. Max-Forwards
Max-Forwards 头字段提供了一个机制,用于限制 TRACE 和 OPTIONS 请求方法的转发次数。
5.2. Conditionals
HTTP 条件请求头字段允许客户端根据目标资源的状态设置前提条件。
5.3. Content Negotiation
以下请求头字段用于主动协商响应内容:
- Accept
- Accept-Charset
- Accept-Encoding
- Accept-Language
5.4. Authentication Credentials
两个头字段用于携带认证凭据:
- Authorization
- Proxy-Authorization
5.5. Request Context
以下请求头字段提供有关请求上下文的附加信息:
- From
- Referer
- User-Agent
6. Response Status Codes
状态码是一个三位数字代码,表示理解和满足请求的结果。
6.1. Overview of Status Codes
状态码分为五类:
- 1xx (Informational)
- 2xx (Successful)
- 3xx (Redirection)
- 4xx (Client Error)
- 5xx (Server Error)
6.2. Informational 1xx
1xx(信息性)状态码表示中间响应,用于在完成请求操作并发送最终响应之前通信连接状态或请求进度。
6.3. Successful 2xx
2xx(成功)状态码表示客户端的请求已成功接收、理解和接受。
6.4. Redirection 3xx
3xx(重定向)状态码表示需要用户代理采取进一步操作以完成请求。
6.5. Client Error 4xx
4xx(客户端错误)状态码表示客户端似乎发生了错误。
6.6. Server Error 5xx
5xx(服务器错误)状态码表示服务器知道它出错或无法执行请求方法。
7. Response Header Fields
响应头字段允许服务器传递关于响应的附加信息。
7.1. Control Data
响应头字段可以提供补充状态码的控制数据,指示缓存或指示客户端下一步操作。
7.2. Validator Header Fields
验证器头字段传达有关选择表示的元数据。
7.3. Authentication Challenges
认证挑战指示客户端在将来的请求中提供认证凭据的机制。
7.4. Response Context
剩余的响应头字段提供有关目标资源的更多信息,以供将来请求使用。
ABNF
Accept = [ ( "," / ( media-range [ accept-params ] ) ) *( OWS "," [ OWS ( media-range [ accept-params ] ) ] ) ]
Accept-Charset = *( "," OWS ) ( ( charset / "*" ) [ weight ] ) *( OWS "," [ OWS ( ( charset / "*" ) [ weight ] ) ] )
Accept-Encoding = [ ( "," / ( codings [ weight ] ) ) *( OWS "," [ OWS ( codings [ weight ] ) ] ) ]
Accept-Language = *( "," OWS ) ( language-range [ weight ] ) *( OWS "," [ OWS ( language-range [ weight ] ) ] )
Allow = [ ( "," / method ) *( OWS "," [ OWS method ] ) ]
BWS = <BWS, see [RFC7230], Section 3.2.3>
Content-Encoding = *( "," OWS ) content-coding *( OWS "," [ OWS content-coding ] )
Content-Language = *( "," OWS ) language-tag *( OWS "," [ OWS language-tag ] )
Content-Location = absolute-URI / partial-URI
Content-Type = media-type
Date = HTTP-date
Expect = "100-continue"
From = mailbox
GMT = %x47.4D.54 ; GMT
HTTP-date = IMF-fixdate / obs-date
IMF-fixdate = day-name "," SP date1 SP time-of-day SP GMT
Location = URI-reference
Max-Forwards = 1*DIGIT
OWS = <OWS, see [RFC7230], Section 3.2.3>
RWS = <RWS, see [RFC7230], Section 3.2.3>
Referer = absolute-URI / partial-URI
Retry-After = HTTP-date / delay-seconds
Server = product *( RWS ( product / comment ) )
URI-reference = <URI-reference, see [RFC7230], Section 2.7>
User-Agent = product *( RWS ( product / comment ) )
Vary = "*" / ( *( "," OWS ) field-name *( OWS "," [ OWS field-name ] ) )
absolute-URI = <absolute-URI, see [RFC7230], Section 2.7>
accept-ext = OWS ";" OWS token [ "=" ( token / quoted-string ) ]
accept-params = weight *accept-ext
asctime-date = day-name SP date3 SP time-of-day SP year
charset = token
codings = content-coding / "identity" / "*"
comment = <comment, see [RFC7230], Section 3.2.6>
content-coding = token
date1 = day SP month SP year
date2 = day "-" month "-" 2DIGIT
date3 = month SP ( 2DIGIT / ( SP DIGIT ) )
day = 2DIGIT
day-name = %x4D.6F.6E ; Mon
/ %x54.75.65 ; Tue
/ %x57.65.64 ; Wed
/ %x54.68.75 ; Thu
/ %x46.72.69 ; Fri
/ %x53.61.74 ; Sat
/ %x53.75.6E ; Sun
day-name-l = %x4D.6F.6E.64.61.79 ; Monday
/ %x54.75.65.73.64.61.79 ; Tuesday
/ %x57.65.64.6E.65.73.64.61.79 ; Wednesday
/ %x54.68.75.72.73.64.61.79 ; Thursday
/ %x46.72.69.64.61.79 ; Friday
/ %x53.61.74.75.72.64.61.79 ; Saturday
/ %x53.75.6E.64.61.79 ; Sunday
delay-seconds = 1*DIGIT
field-name = <comment, see [RFC7230], Section 3.2>
hour = 2DIGIT
language-range = <language-range, see [RFC4647], Section 2.1>
language-tag = <Language-Tag, see [RFC5646], Section 2.1>
mailbox = <mailbox, see [RFC5322], Section 3.4>
media-range = ( "*/*" / ( type "/*" ) / ( type "/" subtype ) ) *( OWS ";" OWS parameter )
media-type = type "/" subtype *( OWS ";" OWS parameter )
method = token
minute = 2DIGIT
month = %x4A.61.6E ; Jan
/ %x46.65.62 ; Feb
/ %x4D.61.72 ; Mar
/ %x41.70.72 ; Apr
/ %x4D.61.79 ; May
/ %x4A.75.6E ; Jun
/ %x4A.75.6C ; Jul
/ %x41.75.67 ; Aug
/ %x53.65.70 ; Sep
/ %x4F.63.74 ; Oct
/ %x4E.6F.76 ; Nov
/ %x44.65.63 ; Dec
obs-date = rfc850-date / asctime-date
parameter = token "=" ( token / quoted-string )
partial-URI = <partial-URI, see [RFC7230], Section 2.7>
product = token [ "/" product-version ]
product-version = token
quoted-string = <quoted-string, see [RFC7230], Section 3.2.6>
qvalue = ( "0" [ "." *3DIGIT ] ) / ( "1" [ "." *3"0" ] )
rfc850-date = day-name-l "," SP date2 SP time-of-day SP GMT
second = 2DIGIT
subtype = token
time-of-day = hour ":" minute ":" second
token = <token, see [RFC7230], Section 3.2.6>
type = token
weight = OWS ";" OWS "q=" qvalue
year = 4DIGIT