因为公司的业务是前后端分离,web前端和后端接口域名不同,所以存在跨域问题,开始使用的是jsonp解决,但是因为接口风格是rest的,还有delete、put等请求,jsonp就不够用了(涉及HTTP简单请求和复杂请求,这里有详细介绍),因此就找到了CORS跨域解决方案。原理过长,所以本篇文章只写服务端代码实现部分。

代码实现

app/Http/Middleware 里新建一个CorsMiddleware.php,并写入如下代码:


<?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 里注册一下全局中间件即可完成


$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的网站请求数据。

原文地址:https://www.jianshu.com/p/ce6a14a4a270

lumen使用CORS解决跨域问题的更多相关文章

  1. 一步一步学习SignalR进行实时通信_3_通过CORS解决跨域

    原文:一步一步学习SignalR进行实时通信_3_通过CORS解决跨域 一步一步学习SignalR进行实时通信\_3_通过CORS解决跨域 SignalR 一步一步学习SignalR进行实时通信_3_ ...

  2. Spring Boot中通过CORS解决跨域问题

    今天和小伙伴们来聊一聊通过CORS解决跨域问题. 同源策略 很多人对跨域有一种误解,以为这是前端的事,和后端没关系,其实不是这样的,说到跨域,就不得不说说浏览器的同源策略. 同源策略是由Netscap ...

  3. Django使用jsonp和cors解决跨域请求问题

    1.使用jsonp的方式解决跨域请求的问题 我启动两个django项目,然后使用的端口不一样,在项目1中通过ajax发请求给项目2,然后接受项目2发送过来的数据 先看项目1的ajax的代码 $(&qu ...

  4. 使用cors解决跨域遇到浏览器发出options嗅探

    前言: 本地开发起的服务器,通过修改hosts文件设置域名映射到本地,接口在测试环境 1. 服务器端设置cors, 配置access-control-allow-origin 头部 使用蚂蚁金服的up ...

  5. 配置CORS解决跨域调用—反思思考问题的方式

    导读:最近都在用一套完整的Java EE的体系做系统,之前都是用spring框架,现在弄这个Java EE,觉得新鲜又刺激.但,由于之前没有过多的研究和使用,在应用的过程中,也出现了不少的问题.累积了 ...

  6. Spring Boot2 系列教程(十四)CORS 解决跨域问题

    今天和小伙伴们来聊一聊通过CORS解决跨域问题. 同源策略 很多人对跨域有一种误解,以为这是前端的事,和后端没关系,其实不是这样的,说到跨域,就不得不说说浏览器的同源策略. 同源策略是由 Netsca ...

  7. 服务端 CORS 解决跨域

    当协议.域名.端口中任一个不同时产生跨域 CORS 跨域资源共享(Cross-origin resource sharing) 参考资料https://developer.mozilla.org/zh ...

  8. 14 微服务电商【黑马乐优商城】:day06-使用nginx反向代理并掌握cors解决跨域

    本项目的笔记和资料的Download,请点击这一句话自行获取. day01-springboot(理论篇) :day01-springboot(实践篇) day02-springcloud(理论篇一) ...

  9. Web API中使用CORS解决跨域

    Web API中使用Cros解决跨域 如果两个页面的协议,端口和域名都相同,则两个页面具有相同的源,注:IE不考虑端口,同源策略不会阻止浏览器发送请求,但是它会阻止应用程序看到响应.如下图所示 COR ...

随机推荐

  1. Spring MVC上传、下载 文件

    1,上传文件 public static String upload(MultipartFile file, SysUserBean sysUserBean, HttpServletRequest r ...

  2. eclipse 克隆 https 地址的 Git 仓库报错:cannot open git-upload-pack

    解决方法:Window >Preferences >Team>Git>User settings点击Add Entry设置key:http.sslVerify value:fa ...

  3. Shutdown- Linux必学的60个命令

    1.作用 shutdown命令的作用是关闭计算机,它的使用权限是超级用户. 2.格式 shutdown [-h][-i][-k][-m][-t] 3.重要参数 -t:在改变到其它运行级别之前,告诉in ...

  4. SQFREE - Square-free integers

    SQFREE - Square-free integers 求n以内,约数中不包含任意一个平方数的个数,\(n≤10^{14}\). 解 显然为约数计数问题,于是想办法转换为代数问题,不难列出 \[a ...

  5. LoadRunner添加Weblogic监控的注意事项(非单纯的操作步骤)

    LoadRunner添加Weblogic监控的注意事项(非单纯的操作步骤)   关于LR如何监控Weblogic(JMX方式)的操作就不在这里多说了,帮助文件和网上的介绍已经非常多了,关键是对各操作步 ...

  6. 0810NOIP模拟测试赛后总结

    明日之后将是什么. 悲哀, 还是希望? 60分我没脸了…… 所以T1好不容易想到了正解结果实现打挂w0了…… 贪心想的还是相当完美的. 不知道我咋想的开了1e6个栈然后dfs模拟结果MLE原地自爆…… ...

  7. Python-线程(1)

    目录 什么是线程 进程与线程的区别 开启线程 为什么要使用线程 线程之间数据是共享的 什么是线程 线程与进程都是虚拟单位,目的是为了更好的描述某种事物 进程与线程的区别 进程:资源单位 线程:执行单位 ...

  8. .git文件夹太大问题及解决方法

    最近我们做了自动化构建, 发现文件.git文件夹越来越大, 求后端小伙伴帮忙, 小伙伴指点了一下说周末弄了一下, 忘记命令的.大致的意思就是找到git 提交了哪些大文件. 然后重构git, 先分享给小 ...

  9. Vue生命周期的执行过程(面试必备) 极简版

    最近准备面试,临时抱佛脚的来回顾一下vue相关的面试题,当然这是不对的,平时还是要努力呀,走起: 1.创建vue实例,Vue(); 2.在创建Vue实例的时候,执行了init(),在init过程中首先 ...

  10. 【breathandlife】气势磅礴、比较好听的旋律有哪些?

    [breathandlife]气势磅礴.比较好听的旋律有哪些? 分享:yunbest作者:来源:2015-10-26 专题:breathandlife [breathandlife]气势磅礴.比较好听 ...