HTTP状态码与自定义头部详解
1. 4xx系列:客户端错误状态码
在HTTP通信中,4xx系列状态码用于表示客户端出现的错误。下面为你详细介绍一些常见的4xx状态码。
| 状态码 | 重要性 | 含义 |
|---|---|---|
| 400 (“Bad Request”) | 高 | 这是通用的客户端错误状态,当没有其他4xx错误代码适用时使用。常见于客户端在PUT或POST请求中提交的表示形式格式正确,但没有实际意义的情况。实体主体可能包含一个文档,描述服务器认为存在客户端错误的原因。 |
| 401 (“Unauthorized”) | 高 | 客户端在未提供适当的身份验证凭据的情况下尝试操作受保护的资源。可能是提供了错误的凭据,或者根本没有提供。凭据可以是用户名和密码、API密钥或身份验证令牌等。服务器的WWW - Authenticate响应头描述了它将接受的身份验证类型。实体主体包含描述失败原因的文档,如凭据被拒绝的原因以及可接受的凭据类型。 |
| 402 (“Payment Required”) | 无 | 除了名称外,此状态码未在HTTP标准中定义,是“留作将来使用”。因为目前没有用于HTTP的微支付系统,但如果未来有,Web服务可能会首先使用。不过像Amazon S3按请求收费时也未使用此状态码。 |
| 403 (“Forbidden”) | 中 | 客户端的请求格式正确,但服务器不想执行该请求。这不是仅仅因为凭据不足(那是401),可能是资源仅在特定时间或特定IP地址可访问。如果服务器不想透露资源的存在信息,可能会返回404。实体主体可选择包含描述请求被拒绝原因的文档。 |
| 404 (“Not Found”) | 高 | 可能是最著名的HTTP状态码。表示服务器无法将客户端的URI映射到资源。Web服务可能将404响应作为信号,告知客户端该URI“可用”,客户端可通过向该URI发送PUT请求创建新资源。但要注意,404可能是为掩盖401或403而撒的谎。 |
| 405 (“Method Not Allowed”) | 中 | 客户端尝试使用资源不支持的HTTP方法。响应头的Allow字段列出了该资源支持的HTTP方法,例如:Allow: GET, POST。 |
| 406 (“Not Acceptable”) | 中 | 当客户端对可接受的表示形式设置了过多限制,导致服务器无法发送任何表示形式时,服务器可能发送此响应码。服务器也可选择忽略客户端的要求,直接发送其首选的表示形式并返回200状态码。实体主体包含可接受表示形式的链接列表。 |
| 407 (“Proxy Authentication Required”) | 低 | 仅会从HTTP代理收到此状态码。类似于401,但问题在于使用代理需要凭据。客户端使用Proxy - Authorization请求头向代理发送凭据,代理在Proxy - Authenticate响应头中描述期望的身份验证类型。 |
| 408 (“Request Timeout”) | 低 | 如果HTTP客户端打开与服务器的连接,但从未发送请求(或未发送表示请求结束的空行),服务器最终应发送408响应码并关闭连接。 |
| 409 (“Conflict”) | 高 | 表示客户端试图使服务器的资源处于不可能或不一致的状态。例如,尝试删除非空的存储桶(如Amazon S3)或更改用户名时使用了已被占用的名称。如果冲突是由其他资源的存在引起的,Location响应头应指向该资源的URI。实体主体应包含描述冲突的文档,以便客户端尽可能解决冲突。 |
| 410 (“Gone”) | 中 | 类似于404,但提供了更多信息。用于服务器知道请求的URI曾经指向一个资源,但现在不再指向的情况。服务器不知道该资源的新URI,如果知道会发送301。客户端应从其词汇表中删除当前URI,停止对其进行请求。成功的DELETE请求应返回200,而不是410。 |
| 411 (“Length Required”) | 低到中 | 包含表示形式的HTTP请求应设置Content - Length请求头为表示形式的字节长度。但HTTP不要求客户端每次请求都发送该头,不过服务器有权对特定请求要求该头。如果客户端在未提供Content - Length的情况下开始发送表示形式,服务器可中断请求并要求客户端重新提交带有该头的请求。 |
| 412 (“Precondition Failed”) | 中 | 客户端在请求头中指定了一个或多个先决条件,服务器只有在满足这些条件时才会执行请求。如果条件未满足,服务器发送此状态码。常见的先决条件如If - Unmodified - Since。如果客户端在GET或HEAD请求中使用If - None - Match且先决条件失败,响应码为304;在PUT、POST或DELETE请求中使用且先决条件失败,响应码为412。 |
| 413 (“Request Entity Too Large”) | 低到中 | 服务器可以用此状态码中断客户端的请求并关闭连接,适用于客户端发送的表示形式太大,服务器无法处理的情况。客户端可通过“先查看后行动”(LBYL)请求避免此错误。如果问题是临时的且在服务器端(如资源不足),服务器可设置Retry - After响应头,让客户端稍后重试请求。 |
| 414 (“Request - URI Too Long”) | 低 | HTTP标准对URI长度没有官方限制,但大多数现有Web服务器会设置上限。常见原因是客户端将表示数据放在URI中,而应放在实体主体中,或者嵌套较深的数据结构导致URI过长。 |
| 415 (“Unsupported Media Type”) | 中 | 当客户端发送服务器不理解的媒体类型的表示形式时,服务器发送此状态码。如果客户端发送的文档媒体类型正确但格式错误,更合适的响应是400;若想特殊处理,可发送WebDAV扩展响应码422。 |
| 416 (“Requested Range Not Satisfiable”) | 低 | 当客户端请求表示形式的一系列字节范围,但表示形式实际上太小,没有任何字节范围适用时,服务器发送此状态码。只有在原始请求包含Range请求头字段时才会发送,若包含If - Range字段则不会发送。服务器应发送Content - Range字段告知客户端表示形式的实际大小。 |
| 417 (“Expectation Failed”) | 中(目前很少使用) | 与100 (“Continue”)相反。如果客户端进行LBYL请求以查看服务器是否接受其表示形式,服务器决定接受则返回100,客户端可继续发送;若服务器决定不接受,则返回417,客户端不应再发送表示形式。 |
下面是客户端请求可能遇到4xx错误的流程:
graph TD
A[客户端发送请求] --> B{请求是否格式正确}
B -- 否 --> C(400 Bad Request)
B -- 是 --> D{是否提供有效凭据}
D -- 否 --> E(401 Unauthorized)
D -- 是 --> F{服务器是否允许执行请求}
F -- 否 --> G(403 Forbidden)
F -- 是 --> H{资源是否存在}
H -- 否 --> I(404 Not Found)
H -- 是 --> J{请求方法是否支持}
J -- 否 --> K(405 Method Not Allowed)
J -- 是 --> L{是否满足先决条件}
L -- 否 --> M(412 Precondition Failed)
L -- 是 --> N{表示形式是否符合要求}
N -- 否 --> O(415 Unsupported Media Type)
N -- 是 --> P{表示形式大小是否合适}
P -- 否 --> Q(413 Request Entity Too Large)
P -- 是 --> R(请求正常处理)
2. 5xx系列:服务器端错误状态码
5xx系列状态码表示服务器端出现的问题。通常意味着服务器无法运行客户端的请求,客户端应稍后重试。有时服务器可以估计客户端应何时重试,并在Retry - After响应头中提供该信息。
| 状态码 | 重要性 | 含义 |
|---|---|---|
| 500 (“Internal Server Error”) | 高 | 这是通用的服务器错误响应。大多数Web框架在运行请求处理代码引发异常时发送此状态码。 |
| 501 (“Not Implemented”) | 低 | 客户端尝试使用服务器不支持的HTTP功能(可能是扩展功能)。常见于客户端使用扩展的HTTP方法,而普通Web服务器不支持,与405不同,405表示客户端使用的是资源不支持的公认方法,而501表示服务器根本不识别该方法。 |
| 502 (“Bad Gateway”) | 低 | 仅会从HTTP代理收到此响应码。表示代理或代理与上游服务器之间存在问题,而非上游服务器本身的问题。如果代理根本无法连接到上游服务器,响应码为504。 |
| 503 (“Service Unavailable”) | 中到高 | 表示HTTP服务器正常运行,但底层Web服务工作不正常。最可能的原因是资源不足,请求过多,服务器无法全部处理。服务器可选择拒绝客户端请求,也可发送Retry - After头告知客户端何时可再次尝试提交请求。 |
| 504 (“Gateway Timeout”) | 低 | 类似于502,仅从HTTP代理收到。表示代理无法连接到上游服务器。 |
| 505 (“HTTP Version Not Supported”) | 极低 | 由不支持客户端尝试使用的HTTP版本的服务器发送。由于HTTP 1.1向后兼容0.9和1.0,所以不太可能很快看到此状态码。实体主体应包含描述服务器支持的协议的文档。 |
下面是服务器处理请求可能出现5xx错误的流程:
graph TD
A[服务器接收请求] --> B{服务器是否正常运行}
B -- 否 --> C(500 Internal Server Error)
B -- 是 --> D{是否支持请求的功能}
D -- 否 --> E(501 Not Implemented)
D -- 是 --> F{是否为代理服务器}
F -- 否 --> G(请求正常处理)
F -- 是 --> H{代理是否正常工作}
H -- 否 --> I(502 Bad Gateway)
H -- 是 --> J{能否连接到上游服务器}
J -- 否 --> K(504 Gateway Timeout)
J -- 是 --> L{是否支持客户端的HTTP版本}
L -- 否 --> M(505 HTTP Version Not Supported)
L -- 是 --> N(请求正常处理)
3. HTTP自定义头部
HTTP标准已经有很好的头部指南,但在实际应用中,自定义头部是扩展HTTP的常见方式。只要客户端和服务器就头部的含义达成一致,就可以在请求或响应中发送任何信息。
自定义头部的命名应遵循“X - ”开头的约定,这表明它们是扩展头部,避免与未来的官方HTTP头部冲突。例如,Amazon的S3不仅定义了像X - amz - acl和X - amz - date这样的头部,还规定S3客户端可以发送任何以“X - amz - meta - ”开头的头部,头部名称和值作为键值对与对象关联,方便存储信息。
还有一些自定义头部已成为HTTP的事实上的一部分,如Cookie;或者在重要技术中使用,如WSSE的X - WSSE和Atom发布协议的Slug。在使用自定义头部时,要注意不要重新发明现有头部,不要将应放在实体主体中的内容放在头部,并遵循命名约定。
HTTP状态码与自定义头部详解(续)
4. 自定义头部的使用场景与示例
自定义头部在实际的资源导向型Web服务中有着广泛的应用场景,下面为你详细介绍一些常见的使用场景及示例。
4.1 元数据存储
在处理资源时,我们常常需要存储一些与资源相关的额外信息,这些信息可以通过自定义头部来实现。以Amazon S3为例,它允许客户端发送以“X - amz - meta - ”开头的自定义头部,这些头部的名称和值会作为键值对与对象关联。例如,我们可以为一个存储在S3中的图片对象添加自定义头部来记录图片的拍摄时间、拍摄地点等信息:
X - amz - meta - shooting - time: 2024 - 01 - 01 12:00:00
X - amz - meta - shooting - location: Beijing
4.2 身份验证与授权
自定义头部也可以用于身份验证和授权机制。例如,WSSE(Web Services Security - Encryption)使用X - WSSE头部来传递安全相关的信息,实现对请求的身份验证和授权。以下是一个简单的X - WSSE头部示例:
X - WSSE: UsernameToken Username="user1", PasswordDigest="xxxxxx", Nonce="xxxxxx", Created="2024 - 01 - 01T12:00:00Z"
4.3 资源标识与管理
在一些资源管理系统中,自定义头部可以用于标识和管理资源。例如,Atom发布协议使用Slug头部来为资源提供一个简短的、用户可读的标识符,方便对资源进行管理和引用。示例如下:
Slug: my - blog - post
下面是一个使用自定义头部进行元数据存储的流程示例:
graph TD
A[客户端准备请求] --> B{是否有元数据要存储}
B -- 是 --> C(添加自定义头部)
C --> D(发送请求到服务器)
B -- 否 --> D
D --> E{服务器接收请求}
E --> F(解析自定义头部)
F --> G(将元数据与资源关联存储)
5. 自定义头部的注意事项
虽然自定义头部为HTTP的扩展提供了便利,但在使用时也需要注意一些事项,以确保其正确使用和兼容性。
5.1 避免冲突
在定义自定义头部时,要避免与现有的标准HTTP头部或其他自定义头部冲突。遵循“X - ”开头的命名约定可以有效避免与未来的官方HTTP头部冲突。例如,不要定义名为“Content - Type”的自定义头部,因为这是一个标准的HTTP头部。
5.2 数据放置
不要将应放在实体主体中的内容放在头部。头部的主要作用是传递与请求或响应相关的元数据,而实体主体则用于存储主要的数据内容。例如,将一个大的JSON对象放在头部是不合适的,应该将其放在实体主体中。
5.3 兼容性
确保客户端和服务器都能正确理解和处理自定义头部。在使用自定义头部之前,要确保双方就头部的含义和格式达成一致。例如,如果使用自定义头部进行身份验证,客户端和服务器需要使用相同的加密算法和验证逻辑。
以下是一个检查自定义头部使用是否合规的列表:
1. 检查自定义头部名称是否以“X - ”开头。
2. 确认头部内容是否属于元数据,而非主要数据内容。
3. 验证客户端和服务器是否对头部的含义和格式达成一致。
6. 总结
HTTP状态码和自定义头部在资源导向型Web服务中起着至关重要的作用。4xx系列状态码帮助我们识别和处理客户端错误,5xx系列状态码则用于处理服务器端错误。通过合理使用这些状态码,我们可以更好地与客户端进行沟通,提供准确的错误信息。
自定义头部为HTTP的扩展提供了强大的功能,允许我们在请求和响应中传递额外的信息。在使用自定义头部时,要遵循命名约定,避免冲突,合理放置数据,并确保客户端和服务器的兼容性。
通过深入理解HTTP状态码和自定义头部的使用,我们可以构建更加健壮、灵活和可扩展的资源导向型Web服务。希望本文能对你在实际开发中有所帮助。
超级会员免费看
2万+

被折叠的 条评论
为什么被折叠?



