由于公司的业务是先后端分离,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浏览器