redirect到login页面时,什么是正确的HTTP状态码?

当用户未login并尝试访问需要login的页面时,redirect到login页面的正确的HTTP状态码是什么?

我在问,因为W3C制定的3xx响应代码 都不符合要求:

10.3.1 300多种select

所请求的资源对应于一组表示中的任何一个,每个表示具有其自己的特定位置,并且正在提供代理驱动的协商信息(部分12),使得用户(或用户代理)可以select优选的表示并将其redirect请求到那个位置。

除非是HEAD请求,否则响应应该包含一个实体,该实体包含一个资源特性和位置列表,用户或用户代理可以从中select一个最合适的资源。 实体格式由Content-Type头字段中给出的媒体types指定。 取决于格式和function

用户代理,select最合适的select可以自动执行。 但是,这个规范没有为这种自动select定义任何标准。

如果服务器有优先select的表示,它应该在位置字段中包含该表示的特定URI; 用户代理可以使用位置字段值进行自动redirect。 除非另有说明,否则此响应是可caching的。

10.3.2 301永久移动

被请求的资源已经被分配了一个新的永久性的URI,任何将来对这个资源的引用都应该使用返回的URI之一。 具有链接编辑function的客户端应尽可能将对Request-URI的引用重新链接到服务器返回的一个或多个新引用。 除非另有说明,否则此响应是可caching的。

新的永久URI应该由响应中的位置字段给出。 除非请求方法是HEAD,否则响应的实体应该包含一个超链接到新URI的短超文本注释。

如果接收到301状态代码以响应除GET或HEAD以外的请求,则用户代理不能自动redirect请求,除非用户可以确认,因为这可能会改变发出请求的条件。

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下。 由于redirect有时可能会被改变,所以客户端应该继续使用Request-URI来处理将来的请求。 如果由Cache-Control或Expires标头字段指示,则该响应仅可caching。

临时URI应该由响应中的位置字段给出。 除非请求方法是HEAD,否则响应的实体应该包含一个超链接到新URI的短超文本注释。

如果接收到302状态码来响应除GET或HEAD以外的请求,用户代理不能自动redirect请求,除非用户可以确认,因为这可能会改变发出请求的条件。

  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下find,并且应该在该资源上使用GET方法进行检索。 此方法主要用于允许POST激活的脚本的输出将用户代理redirect到选定的资源。 新的URI不是最初请求的资源的替代参考。 303响应绝不能被caching,但对第二个(redirect的)请求的响应可能是可caching的。

不同的URI应该由响应中的位置字段给出。 除非请求方法是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节中已经指定的那样),caching将正常运行。

  - 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使用弱validation器),响应不能包含其他实体头; 这可以防止caching的实体和更新的标题之间的不一致。

如果304响应指示当前未被高速caching的实体,则高速caching必须忽略该响应并在没有条件的情况下重复该请求。

如果高速caching使用收到的304响应来更新高速caching条目,则高速caching必须更新条目以反映响应中给出的任何新的字段值。

10.3.6 305使用代理

被请求的资源必须通过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临时redirect

请求的资源暂时驻留在不同的URI下。 由于redirect有时可能会被修改,所以客户端应该继续使用Request-URI来处理将来的请求。 如果由Cache-Control或Expires标头字段指示,则该响应仅可caching。

临时URI应该由响应中的位置字段给出。 除非请求方法是HEAD,否则响应实体应该包含一个超链接到新URI的简短超文本注释,因为许多pre-HTTP / 1.1用户代理不了解307的状态。 因此,注释应该包含用户在新的URI上重复原始请求所需的信息。

如果接收到307状态码来响应除GET或HEAD以外的请求,则用户代理不能自动redirect请求,除非用户可以确认,因为这可能会改变发出请求的条件。

我现在使用302,直到我find正确的答案。

更新与结论:

由于HTTP 302与客户端/浏览器具有最佳的兼容性,所以它更好。

我会说303见其他 302发现:

请求的资源暂时驻留在不同的URI下。 由于redirect有时可能会被改变 ,所以客户端应该继续使用Request-URI来处理将来的请求。 如果由Cache-Control或Expires标头字段指示,则该响应仅可caching。

在我看来最符合login页面。 我最初考虑303 see other方面的工作。 经过一番思考,我想说302 Found更合适,因为请求的资源发现,只有另一个页面才能通过它可以访问。 这个响应不会被默认的caching,这也很好。

这是滥用HTTPredirect机制。 如果用户没有被授权,那么你的应用程序必须返回401未经授权 。 如果用户被授权但没有访问请求的资源,则必须返回403 Forbidden

你应该在客户端做redirect,例如通过javascript。 redirect的状态码,因为所需的授权不存在 。 使用30x这不符合HTTP。

我认为适当的解决scheme是HTTP 401(未授权)标题。

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

这个标题的目的就是这个。 但是,而不是redirect到login页面,正确的过程将是这样的:

  • 用户未login尝试访问login受限页面。
  • 系统标识用户没有login
  • 系统返回HTTP 401头,并在相同的响应(而不是redirect)中显示login表单。

这是一个很好的做法,就像提供一个有用的404页面,站点地图链接和search表单一样。

再见。

在Firefox浏览器caching302redirect的情况下,我遇到过这种情况。 这就是为什么我使用307login页面,例如redirect到最新的文章/post/评论/等。

如果您使用的是302,请不要忘记检查caching是否被禁用:

 header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); header('Last-Modified: ' . gmdate('D, d MYH:i:s') . ' GMT'); header('Cache-Control: no-cache'); header('Pragma: no-cache'); header('Cache-Control: post-check=0, pre-check=0', false);