Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 401重定向神奇地导致302重定向_Php_Redirect_Header_Laravel - Fatal编程技术网

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;