代码实现
<?php namespace AppHttpMiddleware; use IlluminateHttpRequest; use IlluminateHttpResponse; class CorsMiddleware { private $headers; private $allow_origin; public function handle(Request $request, Closure $next) { $this->headers = [ 'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE', 'Access-Control-Allow-Headers' => $request->header('Access-Control-Request-Headers'), 'Access-Control-Allow-Credentials' => 'true',//允许客户端发送cookie 'Access-Control-Max-Age' => 1728000 //该字段可选,用来指定本次预检请求的有效期,在此期间,不用发出另一条预检请求。 ]; $this->allow_origin = [ '*' ]; $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : ''; //如果origin不在允许列表内,直接返回403 if ( !in_array('*', $this->allow_origin) || (!in_array('*', $this->allow_origin) && !in_array($origin, $this->allow_origin) && !empty($origin))) return new Response('Forbidden', 403); //如果是复杂请求,先返回一个200,并allow该origin if ($request->isMethod('options')) return $this->setCorsHeaders(new Response('OK', 200), $origin); //如果是简单请求或者非跨域请求,则照常设置header $response = $next($request); $methodVariable = array($response, 'header'); //这个判断是因为在开启session全局中间件之后,频繁的报header方法不存在,所以加上这个判断,存在header方法时才进行header的设置 if (is_callable($methodVariable, false, $callable_name)) { return $this->setCorsHeaders($response, $origin); } return $response; } /** * @param $response * @return mixed */ public function setCorsHeaders($response, $origin) { foreach ($this->headers as $key => $value) { $response->header($key, $value); } if (in_array($origin, $this->allow_origin)) { $response->header('Access-Control-Allow-Origin', $origin); } else { $response->header('Access-Control-Allow-Origin', '*'); } return $response; } }
在 app/Http/Middleware
里新建一个CorsMiddleware.php
,并写入如下代码:
通过数组的形式实现允许多个origin。
在 boostrap/app.php
里注册一下全局中间件即可完成
$app->middleware([
AppHttpMiddlewareCorsMiddleware::class,
]);
注意
默认情况下,cookie是不包括在CORS请求中的,如果服务器要接受cookie,必须设置
'Access-Control-Allow-Credentials'=> 'true'
如果不需要cookie,则必须删除该字段,改false是没用的,这个值只能是true。
如果是更复杂的业务需求,可以把method提出来做相应的逻辑判断。
与JSONP的比较
CORS与JSONP的使用目的相同,但是比JSONP更强大。
JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。