CORS 前端请求跨域时遇到的一些坑 后台解决方法
最近写接口和前端vue交互,这样就需要定义token来验证,之前的项目都是前后台不分离,我们都是服务的使用cookie或session。来存取数据。现在前后端分类,那么token验证是必不可少的,之前由于跨域问题,我们开始的解决办法是每次提交数据都携带token,这样就造成每次提交都带有token,明文传送容易被别人窃取。接下来就展示一下解决跨域遇到的坑。首先遇到的问题就是这个:Acc...
最近写接口和前端vue交互,这样就需要定义token来验证,之前的项目都是前后台不分离,我们都是服务的使用cookie或session。来存取数据。现在前后端分类,那么token验证是必不可少的,之前由于跨域问题,我们开始的解决办法是每次提交数据都携带token,这样就造成每次提交都带有token,明文传送容易被别人窃取。
接下来就展示一下解决跨域遇到的坑。
首先遇到的问题就是这个:Access-Control-Allow-Origin的问题
跨域遇到的第一个问题就是Access-Control-Allow-Origin的错误, Chrome报错Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
这里我们只需要在服务端加上以下代码即可(我这里服务端是php)
header("Access-Control-Allow-Origin: * ");
处理了上述问题后接着请求则又出现报错:因为我是让前端将token设置在请求头中
Access-Control-Allow-Headers的问题
以过上面的代码已经实现了跨域中的第一步,GET请求一切正常. 可是需要POST请求发送数据时又出问题了, Chrome报错Request header field token is not allowed by Access-Control-Allow-Headers in preflight response. 查了下资料,大致意思是请求头中的token字段内容没有在Access-Control-Allow-Headers中被设置为允许.
这个简单,只需要把这个内容加在Access-Control-Allow-Headers上面就行了,顺便也把其它常用的头都加进去吧. 这里的token 是我这边让前端设置请求头的 key值
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Connection, User-Agent, Cookie,token');
OPTIONS请求
以上问题都解决了, 基本上跨域已经搞定, 但仔细看Chrome的Network日志, 发现有些请求会出现两次: 第一次是OPTIONS请求方式, 第二次才是正常的POST. 这个OPTIONS是干嘛的呢?
查了些资料并且测试了下, 发现OPTIONS就是相当于在正式请求接口之前去获取以下header, 自然就是我们前面所设置的那些header. 如果在这次OPTIONS请求中服务器有返回正确的header, 这时才会执行后面真正的请求; 否则请求将会被拒绝, 并抛出错误.
即然这次OPTIONS请求仅仅是为了获取header的, 那么给它一个空的返回就行了呗, 不需要做任何实际的操作.
/*
* 判断 OPTIONS 请求,如果 请求方式为
* OPTIONS ,输出头部直接返回
*/
if(isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'OPTIONS'){
exit();
}
本文也是参考:https://icewing.cc/post/about-cross-origin.html这篇博客的,感谢大佬的分享。
因为我的项目后台是用thinkphp5框架写的,我这边只需要在如果文件加入以上代码即可
// 准许跨域请求。
header("Access-Control-Allow-Origin: * ");
header("Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE");
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Connection, User-Agent, Cookie,token');
/**
* 浏览器第一次在处理复杂请求的时候会先发起OPTIONS请求。路由在处理请求的时候会导致PUT请求失败。
* 在检测到option请求的时候就停止继续执行
*/
if($_SERVER['REQUEST_METHOD'] == 'OPTIONS'){
exit;
}
更多推荐
所有评论(0)