代碼實現
<?php namespace App\Http\Middleware; use Illuminate\Http\Request; use Illuminate\Http\Response; 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([
\App\Http\Middleware\CorsMiddleware::class,
]);
注意
默認情況下,cookie是不包括在CORS請求中的,如果服務器要接受cookie,必須設置
'Access-Control-Allow-Credentials'=> 'true'
如果不需要cookie,則必須刪除該字段,改false是沒用的,這個值只能是true。
如果是更復雜的業務需求,可以把method提出來做相應的邏輯判斷。
與JSONP的比較
CORS與JSONP的使用目的相同,但是比JSONP更強大。
JSONP只支持GET請求,CORS支持所有類型的HTTP請求。JSONP的優勢在於支持老式瀏覽器,以及可以向不支持CORS的網站請求數據。