Php 401重定向神奇地导致302重定向
我使用Php 401重定向神奇地导致302重定向,php,redirect,header,laravel,Php,Redirect,Header,Laravel,我使用Redirect类将未登录的用户发送到登录页面,状态代码为401: return Redirect::to('login', 401); 这将发送正确的位置标头,但状态代码设置为302 我一直追踪到了中的基本Response类 laravel/vendor/Symfony/Component/HttpFoundation/Response.php 它在呼唤: $this->setStatusCode($status); 使用正确的401代码 我也尝试过倾倒这个物体: var_
Redirect
类将未登录的用户发送到登录页面,状态代码为401:
return Redirect::to('login', 401);
这将发送正确的位置标头,但状态代码设置为302
我一直追踪到了中的基本
Response
类
laravel/vendor/Symfony/Component/HttpFoundation/Response.php
它在呼唤:
$this->setStatusCode($status);
使用正确的401代码
我也尝试过倾倒这个物体:
var_dump( Redirect::to('login', 401)->foundation );
我可以看到受保护的statusCode
属性被正确设置为401
不过,生成的响应的HTTP状态代码设置为302 有什么好处?我用错了吗
p.S.I也没有用。这不是因为laravel,您可以使用(windows中的PHP5.4)复制它: 在PHP源代码main/SAPI.C中:
} else if (!STRCASECMP(header_line, "Location")) {
if ((SG(sapi_headers).http_response_code < 300 ||
SG(sapi_headers).http_response_code > 307) &&
SG(sapi_headers).http_response_code != 201) {
/* Return a Found Redirect if one is not already specified */
if (http_response_code) { /* user specified redirect code */
sapi_update_response_code(http_response_code TSRMLS_CC);
} else if (SG(request_info).proto_num > 1000 &&
SG(request_info).request_method &&
strcmp(SG(request_info).request_method, "HEAD") &&
strcmp(SG(request_info).request_method, "GET")) {
sapi_update_response_code(303 TSRMLS_CC);
} else {
sapi_update_response_code(302 TSRMLS_CC);
}
}
这将提供:
$ php-cgi "test.php"
Status: 401 Unauthorized
Location: http://www.google.com
Content-type: text/html; charset=UTF-8
但laravel在设置状态后设置位置,因此状态无论如何都会设置回302。但这是一个没有实际意义的问题,即使您成功地将状态设置为401并带有位置标头,浏览器也不会跟随重定向。浏览器不允许您这样做;你不能用401重定向。我更进一步地跟踪了它。。。直到
laravel/vendor/Symfony/Component/HttpFoundation/Response.php中的public function sendHeaders()
。。。它在其中生成最终状态标头
// status
Header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText));
…当然还是401
然后我明白了。您不能使用401重定向,这是一个ClientError
(它也会使同一Response.php
文件中所述的isRedirect
测试失败。mod_php
会在您发送位置后立即将其修复为302(因为默认状态为200,因此需要更新。php不会检查它是否已更新为其他内容).正如其他人所指出的,没有401重定向这样的事情。我之所以被它吸引是因为,但是
如果您发现自己处于类似的情况,以下是我最终使用的:
return Request::ajax() ?
Response::make('', 401, array('HTTP/1.1 401 Unauthorized')) :
Redirect::to('login', 302);
这使用了Laravel的方法来处理头文件
如果您使用的是香草PHP,请使用以下命令:
$is_ajax_request = ! empty( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
$is_ajax_request ?
header('HTTP/1.1 401 Unauthorized') :
header('Location: http://site.com/login');
exit;
什么操作系统(和服务器)你正在工作吗?在这个重定向之后还有其他不明显的重定向吗?401可能会工作,然后302重定向会在这之后跳入并进行重定向…抓住这里的稻草+1谢谢。有其他方法解决这个问题吗?我希望未经授权的用户被重定向到登录页面,但我还需要我的AJAX请求知道用户何时注销(我使用的方法与这里概述的方法类似)@JosephSilber jQuery在请求上打上X-request-With头,让您知道它是用ajax发出的。然后,您可以为ajax设置401状态,为常规请求设置重定向状态。我想了一下,但在某个地方读到他们计划删除它。现在找不到源。您能确认一下吗?@JosephSilb呃,通过谷歌搜索找不到这方面的任何信息,这看起来很疯狂。所有/大多数ajax库都会使用该标题,这非常有用,因为ajax请求的工作方式非常不同,例如,在响应ajax请求时重定向没有意义。那么,我过去一定有过幻觉。不管怎样,我就是这么采用的lution和它完美地工作。再次感谢。+1感谢你在这一次上一直走到兔子洞。谢谢。
// status
Header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText));
return Request::ajax() ?
Response::make('', 401, array('HTTP/1.1 401 Unauthorized')) :
Redirect::to('login', 302);
$is_ajax_request = ! empty( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
$is_ajax_request ?
header('HTTP/1.1 401 Unauthorized') :
header('Location: http://site.com/login');
exit;