一、什么是CORS
CORS(Cross-Origin Resource Sharing 跨源资源共享),当一个请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。
二、问题描述
本人最近在写商城的CMS 系统时,CMS访问API 就要到了跨域问题:
467AFF64-F9EF-4A6A-AFEE-4256FEA56692.png- 跨域点:
CMS 页面是通过http协议访问的,而CMS要访问的接口却在https上,
url 协议不同,导致跨域。而且还报了了一个访问接口的404错误,
后来查了一下,当浏览器检查到有跨域的问题,会对访问的接口做一个判断,如果是简单的接口,则直接访问,如果是复杂的接口,则需要先发送一个option请求,但是我的路由里面没有定义该接口的option请求 ,因此报了一个404错误
- 规避
后来我想,我的CMS和API都是在同一域名下,不应该存在协议不同问题,后来我又重新用https协议访问了一下CMS。果然问题就解决了。
三、由跨域引起的思考
虽然我现在这个跨域的问题解决了,但是如果后续CMS 和API做分离,还是会遇到跨域问题,所以这个问题必须解决。其实大多数跨域问题,只要在访问的接口中写入下面的一段话就可以解决:
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
header('Access-Control-Allow-Methods: GET,POST');
但是正如上面所说,有些浏览器在检查到跨域问题时,会有两次请求,第一次是option,如果放回200,然后才会正式去访问接口。所以需要在有跨域的地方,都加上一个对option请求的处理,但是如果项目的接口太多,在每个接口都加这样一个判断,显然有点费时费力,此时,AOP思想又再次登场了。
四、利用AOP思想,结合CORS,解决跨域问题
我目前做的微信商城项目是基于thinkPHP5,thinkPHP5对AOP有较好的支持,所谓的AOP 就是面向切面编程的思想。
在thinkPHP的application目录下,有一个tags.php文件,这个能保证加载全局的函数。
4.1
如下图所示,将CORS跨域处理文件的路径定义到app_init下,这就能保证,tp5框架在初始化就加载这个跨域处理函数
屏幕快照 2017-06-30 下午12.06.55.png4.2
在application/api下新建一个behavior文件,并新建一CORS.php跨域处理文件
屏幕快照 2017-06-30 下午12.12.14.png具体代码如下:
namespace app\api\behavior;
class CORS
{
//对应tags.php的app_init 使用驼峰命名,不能修改方法名
public function appInit(&$params)
{
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: token,Origin, X-Requested-With, Content-Type, Accept");
header('Access-Control-Allow-Methods: POST,GET');
if(request()->isOptions()){
exit();
}
}
}
五、验证
WechatIMG2.jpeg为了构造跨域,我的cms 还是用http格式访问,对应的https的api接口
验证成功,在浏览器判断有跨域问题,首先会发起一个options请求,在options请求被tp处理并返回200后,才开始正式访问数据。并成功请求到数据。
网友评论