由於公司的業務是先後端分離,web前端和後端接口域名不一樣,因此存在跨域問題,開始使用的是jsonp解決,可是由於接口風格是rest的,還有delete、put等請求,jsonp就不夠用了(涉及HTTP簡單請求和複雜請求,這裏有詳細介紹),所以就找到了CORS跨域解決方案。原理過長,因此本篇文章只寫服務端代碼實現部分。php
在 app/Http/Middleware
裏新建一個CorsMiddleware.php
,並寫入以下代碼:html
<?php /* * Author:xx_lufei * Time:2016年11月3日13:15:51 * Note:Access Control Headers. */ 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 = [ 'http://localhost', 'http://192.168.1.12:8080' ]; $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : ''; //若是origin不在容許列表內,直接返回403 if (!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; } }
經過數組的形式實現容許多個origin。前端
在 boostrap/app.php
裏註冊一下全局中間件便可完成web
$app->middleware([ \App\Http\Middleware\CorsMiddleware::class, ]);
默認狀況下,cookie是不包括在CORS請求中的,若是服務器要接受cookie,必須設置json
'Access-Control-Allow-Credentials'=> 'true'
若是不須要cookie,則必須刪除該字段,改false是沒用的,這個值只能是true。後端
若是是更復雜的業務需求,能夠把method提出來作相應的邏輯判斷。跨域
CORS與JSONP的使用目的相同,可是比JSONP更強大。
JSONP只支持GET請求,CORS支持全部類型的HTTP請求。JSONP的優點在於支持老式瀏覽器,以及能夠向不支持CORS的網站請求數據。數組
原文地址:https://www.jianshu.com/p/ce6a14a4a270瀏覽器