我正在使用Redirect
类将未登录的用户发送到登录页面,其中包含 401 状态代码:
return Redirect::to('login', 401);
这会发送正确的位置标头,但状态代码设置为 302 。
我一直跟踪到
中的基础Response
类
laravel /供应商/ Symfony的/组件/ HttpFoundation / Response.php
它正在呼唤:
$this->setStatusCode($status);
使用正确的 401 代码。
我也试过转储对象:
var_dump( Redirect::to('login', 401)->foundation );
我可以看到受保护的statusCode
属性已正确设置为 401 。
但是,生成的响应的HTTP状态代码设置为 302 。
是什么给出的?我使用它错了吗?
P.S。我也是posted this on Laravel's forums,但无济于事。
答案 0 :(得分:4)
这不是因为laravel,你可以用(Windows中的PHP 5.4)重现这个:
<?php
header("HTTP/1.1 401 Unauthorized");
header("Location: http://www.google.com");
看来php将其设置为302:
$ php-cgi "test.php"
Status: 302 Moved Temporarily
Location: http://www.google.com
Content-type: text/html; charset=UTF-8
在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);
}
}
正如您所看到的,当header()
"Location"
<?php
header("Location: http://www.google.com");
header("HTTP/1.1 401 Unauthorized");
时,http状态代码被修改为302
如果你这样做,你可以使它工作:
$ php-cgi "test.php"
Status: 401 Unauthorized
Location: http://www.google.com
Content-type: text/html; charset=UTF-8
这将给出:
{{1}}
但是laravel在设置状态后设置位置,因此无论如何状态都会设置回302。但这是一个没有实际意义的问题,即使您使用位置标题成功将状态设置为401,浏览器也不会重定向。
答案 1 :(得分:4)
浏览器不允许你这样做;您无法使用401重定向。
答案 2 :(得分:1)
我跟着它走得更远......直到public function sendHeaders()
laravel/vendor/Symfony/Component/HttpFoundation/Response.php
...它产生最终状态标题
// status
Header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText));
......当然还是401。
然后它恍然大悟。 您无法使用401 重定向,这是一个ClientError。
(同样isRedirect
文件中所述的Response.php
测试也会失败。mod_php
会在您发送Location
后立即将其修复为302(因为默认情况下状态是200,所以需要更新.PHP不会检查它是否已经更新为其他内容。)
答案 3 :(得分:0)
正如其他人所指出的,没有像401重定向这样的东西。我迷上这个原因的原因是I need non-AJAX users to be redirected,但是AJAX requests should get a 401。
如果你发现自己处于类似情况,这就是我最终使用的内容:
return Request::ajax() ?
Response::make('', 401, array('HTTP/1.1 401 Unauthorized')) :
Redirect::to('login', 302);
这使用Laravel的方法来处理标题。
如果您使用的是vanilla 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;