header('Access-Control-Allow-Origin: *');
//允许所有域访问API
header("Access-Control-Allow-Headers: token,Origin,X-Requested-with,Contect-Type,Accept")
//我们允许客户端放我们API,Header允许那些键值对
header('Access-Control-Allow-Methods: POST,GET');
在接口方法加入这个就可以
另外浏览器对于某些类型的HTTP请求,如果HTTP请求跨域的话,他的访问流程分两步走。发GET请求,他首先会把我们服务器接口,发送options请求。options请求必须我们服务器能正确响应他,并且相应结果要附带headers,附带headers的意义就是我允许你跨域访问我们的服务器。只有在Options携带http的headers之后,他才会做第二步访问,第二部才是我们真正的get请求。如果原来只支持get,第一步你发送options请求之后,我们服务器没有接受option方式的接口,只能接受get。option请求没有收到正确的相应,他依然认为服务器不允许跨域。这就是为什么出现了两个错误提示,1 option404找不到,2 服务器不允许跨域
不是所有浏览器都会发options请求,分成两种大的类别。一类叫做简单请求,另外一类叫做复杂请求。对于复杂请求,浏览器会发送options请求。简单就不会了。查CROS 简单请求查的到,逻辑判断比较复杂,这里就不列出来了。
解决:让接口即支持get,还支持options。当我接口很多,我们写API专心于业务逻辑,我们没有理由去关心跨域情况。我们要用AOP思想。我们从切面全局角度,为所有接口做跨域方法。
在我们所有的请求,不关你是什么请求,进行到Controller方法之前,在一个全局位置做一个拦截。看一下,请求是不是option请求。如果是option请求,那么我就不会放行,就会把请求返回回去。并且在返回去的headers附加刚才的headers。这样就可以成功地只用在一个地方写代码,就可以让所有请求得到这样一个支持。那么不是options请求话,我们拦截器就不用管了。继续让他该干嘛干嘛。
TP5提供了行为这样一个机制(其他用中间件更好理解)
默认的行为在application的tag.php
我们在api目录新建一个behavior目录
定义行为类CORS.php
添加方法
public function appInit(&$params)
{
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: token,Origin,X-Requested-with,Contect-Type,Accept")
header('Access-Control-Allow-Methods: POST,GET');
if(requset()->isOptions()){
exit();
}
}
}
当我们应用初始化之后就会执行这个方法。如果判断option请求就不让你走后面流程就直接把这次请求终端,并且返回回去,返回回去的http头带有上面的参数值。这样就可以用全局方式相应HTTP请求。
去tag.php注册'app_init' => [‘app\api\behavior\CORS’],