中间件设置响应头 $request->header 没效果

前端请求有跨域问题,然后设置了群组中间件。


Route::group ( [ 
        'domain' => "api.qipeifeixia.in",
        'namespace' => 'api',
        'middleware' => 'cors'
], function () {
    Route::resource ( 'supplier', 'SupplierController' );
} );

测试过这个中间件是有作用到的。

然而设置了之后并没有什么用,前端请求还是提示跨域问题。

以下中间件代码



namespace App\Http\Middleware;

use Closure;

class CORS
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request)->header('Access-Control-Allow-Origin', '*')
                              ->header("Access-Control-Max-Age", "86400")
                              ->header('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Requested-With')
                              ->header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE, PATCH');
    }
}

一看没效果,然后就去/public/index.php 文件里加了一段同样的头,就没问题了... 所以我想问,为什么写在中间件里没有生效,是哪里操作不对了吗..

下面是写在/public/index.php中的头,和中间件中的其实一样。


header('Access-Control-Allow-Origin: *');
header('Access-Control-Max-Age: 86400');
header('Access-Control-Allow-Headers: Content-Type, Accept, Authorization, X-Requested-With');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE, PATCH');
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 17

header设置在response里面才能输出给客户端,试试直接写在中间件里面吧:

class CORS
{
    public function handle($request, Closure $next)
    {
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Max-Age: 86400');
        header('Access-Control-Allow-Headers: Content-Type, Accept, Authorization, X-Requested-With');
        header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE, PATCH');

        return $next($request);
    }
}
7年前 评论

@song 不行, 各种方式都试了,还是没反应... :astonished:


public function handle($request, Closure $next)
    {
        // 这样
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Max-Age: 86400');
        header('Access-Control-Allow-Headers: Content-Type, Accept, Authorization, X-Requested-With');
        header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE, PATCH');

        // 这样
        $request->header('Access-Control-Allow-Origin', '*')
                ->header("Access-Control-Max-Age", "86400")
                ->header('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Requested-With')
                ->header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE, PATCH');

        // 这样
        return $next($request)->header('Access-Control-Allow-Origin', '*')
                              ->header("Access-Control-Max-Age", "86400")
                              ->header('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Requested-With')
                              ->header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE, PATCH');
    }
7年前 评论

经测试 我上面的代码在laravel 5.3下面能输出设置的header

7年前 评论

@song 是版本问题吗.. 我5.0的.. 还有啥解决办法吗。

7年前 评论

我也遇到类似的情况了

请检查自己是否使用了辅助函数dump()或者dd(),
Cannot modify header information - headers already sent by (output started at ********\/vendor\/symfony\/var-dumper\/Dumper\/AbstractDumper.php:180)

或者通过header()检查 header 在哪里提前发送了

$response = $next($request);
header('anykey', 'anyvalue');
return $response;

以上仅我遇到的情况
另外很神奇的是关掉dump()之后,其他处理请求之后添加header的方法都管用, 就header()无效,可能是没有自动识别被继承的Response::class。不过我的问题已解决暂时不管了。

6年前 评论

我也遇到这种问题了,本地测试可以,一到线上就不行了,是我设置了ob_clean();的原因吗?

5年前 评论
AspireHe

laravel 需要消息认证请求 ,默认不允许跨域请求资源,消息认证请求需要手动设置XMLHttpRequest 实例

5年前 评论

请问你们是怎么写的啊,我版本5.5,按你上面设置了header, ajax 返回打印都是undefined,上面都获取不到

file

5年前 评论

出现相同的问题,跨域都无法解决,版本5.7,用了dingo

5年前 评论
ruke

很有可能是你的 web 服务的问题, 我之前用lumen5.4也有过这种问题, 因为nginx好像还会过滤或者重置一些header之类的

5年前 评论

不是web的问题,是我用dingo,然后next($request)就直接跳转到下个中间件了,没有在本中间走下去。现在不知道问题出在那

file

5年前 评论

试试这个

$request->headers->set('header_key', 'header_value');

完整示例

    public function handle($request, Closure $next)
    {
        $request->headers->set('Access-Control-Allow-Origin', '*');
        $request->headers->set("Access-Control-Max-Age", "86400");
        $request->headers->set('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Requested-With');
        $request->headers->set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE, PATCH');

        return $next($request);
    }
5年前 评论

终于找到出现同样问题的人了,是不是因为控制器里面有打印 才会那样啊

5年前 评论
66

试试 barryvdh大神的laravel-cors
目前我都是用这个来了解决 跨域问题

5年前 评论

我无效的原因是我继承的控制器里存在session 将session注释掉后 中间件配置的响应头有效 但如何让他们共存呢 就像原生php里面顶部添加缓冲ob_start()一样

5年前 评论

楼主这个响应问题解决了吗?

4年前 评论
又遇到同样的问题,
大概搞清楚了,一般跨域分为两种,
简单请求和非简单请求。
简单请求,服务器端设置header: Access-Control-Allow-Origin:'*'
然后把结果返回给前端。
非简单请求,http会实现发送预请求,请求方式options,
服务端设置如下:
Access-Control-Request-Method
Access-Control-Request-Headers
Access-Control-Max-Age
预检通过,然后http第二次发送请求。

在路由页设置header是可以跨域的,那为什么中间件跨域失败。
大概是这样
假设我们请求的URL是http://localhost:8080/api/test,请求方式是OPTIONS。
如果请求的URL不存在相关的其它方式(如GET或POST)的请求,则会返回404 NOT FOUND的错误。
如果存在相同URL的请求,会返回一个状态码为200的成功响应,但没有任何额外内容。

问题就出在这里了。
相关链接:https://blog.csdn.net/qq_36427770/article/details/83276478
4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!