当用户未登录并尝试访问需要登录的页面时,重定向到登录页面的正确 HTTP 状态代码是什么?
我之所以问,是因为W3C 规定的 3xx 响应代码 似乎都不符合要求:
10.3.1 300 多项选择
请求的资源对应于一组表示中的任何一个,每个表示都有自己的特定位置,并且正在提供代理驱动的协商信息(第 12 节),以便用户(或用户代理)可以选择首选表示并重定向其请求该位置。
除非它是一个 HEAD 请求,否则响应应该包含一个实体,该实体包含一个资源特征和位置列表,用户或用户代理可以从中选择最合适的一个。实体格式由 ContentType 标头字段中给出的媒体类型指定。取决于格式和能力
用户代理,最合适的选择可能会自动执行。但是,本规范没有为这种自动选择定义任何标准。
如果服务器有首选的表示形式,它应该在 Location 字段中包含该表示形式的特定 URI;用户代理可以使用 Location 字段值进行自动重定向。除非另有说明,否则此响应是可缓存的。
10.3.2 301 永久移动
请求的资源已被分配一个新的永久 URI,并且任何将来对该资源的引用都应该使用返回的 URI 之一。如果可能,具有链接编辑功能的客户端应该自动将对 Request-URI 的引用重新链接到服务器返回的一个或多个新引用。除非另有说明,否则此响应是可缓存的。
新的永久 URI 应该由响应中的 Location 字段给出。除非请求方法是 HEAD,否则响应的实体应该包含一个简短的超文本注释,其中包含指向新 URI 的超链接。
如果收到 301 状态代码以响应 GET 或 HEAD 以外的请求,用户代理不得自动重定向请求,除非用户可以确认,因为这可能会改变发出请求的条件。
Note: When automatically redirecting a POST request after receiving a 301 status code, some existing HTTP/1.0 user agents will erroneously change it into a GET request.10.3.3 302 找到
请求的资源临时驻留在不同的 URI 下。由于重定向有时可能会改变,客户端应该继续使用 Request-URI 来处理未来的请求。此响应仅在由 Cache-Control 或 Expires 标头字段指示时才可缓存。
临时 URI 应该由响应中的 Location 字段给出。除非请求方法是 HEAD,否则响应的实体应该包含一个简短的超文本注释,其中包含指向新 URI 的超链接。
如果收到 302 状态码以响应 GET 或 HEAD 以外的请求,除非用户可以确认,否则用户代理不得自动重定向请求,因为这可能会改变发出请求的条件。
Note: RFC 1945 and RFC 2068 specify that the client is not allowed to change the method on the redirected request. However, most existing user agent implementations treat 302 as if it是 303 响应,无论原始请求方法如何,都对 Location 字段值执行 GET。状态码 303 和 307 已被添加用于希望明确明确期望客户端做出何种反应的服务器。
10.3.4 303 见其他
可以在不同的 URI 下找到对请求的响应,并且应该使用该资源上的 GET 方法来检索。此方法的存在主要是为了允许 POST 激活脚本的输出将用户代理重定向到选定的资源。新的 URI 不是原始请求资源的替代引用。303 响应不能被缓存,但对第二个(重定向)请求的响应可能是可缓存的。
不同的 URI 应该由响应中的 Location 字段给出。除非请求方法是 HEAD,否则响应的实体应该包含一个简短的超文本注释,其中包含指向新 URI 的超链接。
Note: Many pre-HTTP/1.1 user agents do not understand the 303 status. When interoperability with such clients is a concern, the 302 status code may be used instead, since most user agents react to a 302 response as described here for 303.10.3.5 304 未修改
如果客户端已经执行了一个条件 GET 请求并且允许访问,但是文档没有被修改,服务器应该用这个状态码来响应。304 响应不能包含消息体,因此总是由头字段之后的第一个空行终止。
响应必须包含以下标头字段:
- Date, unless its omission is required by section 14.18.1 If a无时钟源服务器遵循这些规则,并且代理和客户端将自己的 Date 添加到没有收到的任何响应中(如 [RFC 2068] 第 14.19 节已指定),缓存将正确运行。
- ETag and/or Content-Location, if the header would have been sent in a 200 response to the same request - Expires, Cache-Control, and/or Vary, if the field-value might differ from that sent in any previous response for the same variant If the conditional GET used a strong cache validator (see第 13.3.3 节),响应不应包含其他实体标头。否则(即,条件 GET 使用弱验证器),响应不得包含其他实体标头;这可以防止缓存的实体主体和更新的标头之间的不一致。
如果 304 响应指示当前未缓存的实体,则缓存必须忽略响应并在没有条件的情况下重复请求。
如果缓存使用接收到的 304 响应来更新缓存条目,则缓存必须更新该条目以反映响应中给出的任何新字段值。
10.3.6 305 使用代理
请求的资源必须通过 Location 字段给出的代理访问。Location 字段给出了代理的 URI。接收者应该通过代理重复这个单一的请求。305 响应必须只能由源服务器生成。
Note: RFC 2068 was not clear that 305 was intended to redirect a single request, and to be generated by origin servers only. Not observing these limitations has significant security consequences.10.3.7 306(未使用)
306 状态码在以前的规范版本中使用,不再使用,代码被保留。
10.3.8 307 临时重定向
请求的资源临时驻留在不同的 URI 下。由于重定向有时可能会改变,客户端应该继续使用 Request-URI 来处理未来的请求。此响应仅在由 Cache-Control 或 Expires 标头字段指示时才可缓存。
临时 URI 应该由响应中的 Location 字段给出。除非请求方法是 HEAD,否则响应的实体应该包含一个简短的超文本注释,其中包含指向新 URI 的超链接,因为许多 HTTP/1.1 之前的用户代理不理解 307 状态。因此,注释应该包含用户在新 URI 上重复原始请求所需的信息。
如果收到 307 状态代码以响应 GET 或 HEAD 以外的请求,则用户代理不得自动重定向请求,除非用户可以确认,因为这可能会改变发出请求的条件。
我现在使用 302,直到我找到正确的答案。
更新和结论:
HTTP 302 更好,因为它与客户端/浏览器具有最佳兼容性。