157

当用户未登录并尝试访问需要登录的页面时,重定向到登录页面的正确 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 更好,因为它与客户端/浏览器具有最佳兼容性。

4

3 回答 3

83

我会说303 看到其他 302 Found:

请求的资源临时驻留在不同的 URI 下。由于重定向有时可能会改变,客户端应该继续使用 Request-URI 来处理未来的请求。此响应仅在由 Cache-Control 或 Expires 标头字段指示时才可缓存。

我认为最适合登录页面。我最初考虑303 see other过哪个也可以。经过一番思考,我会说302 Found更合适,因为找到了请求的资源只有另一个页面要经过才能访问。默认情况下,响应不会被缓存,这也很好。

于 2010-05-15T09:21:47.163 回答
57

这是对 HTTP 重定向机制的误用。如果用户未获得授权,那么您的应用程序必须返回401 Unauthorized。如果用户被授权但无权访问所请求的资源,则403 Forbidden必须返回。

您应该在客户端进行重定向,例如通过 javascript。重定向的状态码,因为所需的授权不存在。为此使用 30x 不符合 HTTP。

如何思考 HTTP 状态码 作者 Mark Nottingham

401 Unauthorized 触发 HTTP 的请求认证机制。

401 Unauthorized状态码需要存在WWW-Authenticate支持各种身份验证类型的标头:

WWW-Authenticate: <type> 领域=<领域>

Bearer、OAuth、Basic、Digest、Cookie 等

于 2013-03-08T20:00:50.990 回答
12

我认为适当的解决方案是 HTTP 401(未授权)标头。

http://en.wikipedia.org/wiki/HTTP_codes#4xx_Client_Error

此标头的目的正是如此。但是,正确的过程不是重定向到登录页面,而是如下所示:

  • 未登录的用户尝试访问登录限制页面。
  • 系统识别用户未登录
  • 系统返回 HTTP 401 标头,并在同一响应中显示登录表单(不是重定向)。

这是一个很好的做法,例如提供有用的 404 页面、站点地图链接和搜索表单。

再见。

于 2010-05-28T17:25:49.007 回答