1、问题原因
实际项目开发中,我们经常前后端分离,前端代码工程与后端代码工程分别部署在不同的服务器上,然后这个时候再做前后端通信的时候就会出现跨域的情况。
这个操作分为两个部分,刚开始是前端发起对后端程序的访问,这个是可以操作的,并且后端程序也返回了response给前端,只是在浏览器的安全策略处理上不允许这类数据的接受。
这个主要是由于浏览器的同源策略的限制,现在所有支持JavaScript的浏览器基本都采用这种策略(注意是JavaScript才有同源策略 )。同源策略体现在三个方面:
(1)协议相同
(2)域名相同
(3)端口相同
例如下面的几个URL是否存在跨域问题:
同一协议,同一域名,同一端口号 ,允许通信
同一协议,不同域名,同一端口号,不允许通信
同一协议,同一域名,不同端口 ,不允许通信
不同协议,同一域名,同一端口号,不允许通信
2、解决方案
1)后端代码在返回的response中添加header设置
response.setHeader("Access-Control-Allow-Origin", "*");
Access-Control-Allow-Origin: 允许跨域访问的域,可以是一个域的列表,也可以是通配符"*"。这里要注意Origin规则只对域名有效,并不会对子目录有效。即http://www.a.com/b/ 是无效的。但是不同子域名需要分开设置,这里的规则可以参照同源策略。
Access-Control-Allow-Origin: * 允许任何来自任意域的跨域请求,会存在被 DDOS攻击的可能。
2)通过JSONP进行跨域处理
JSONP与JSON是不同的东西,JSON是一种数据交换的格式,JSONP是一种非官方跨域数据交换协议。
前端JS代码:
$.ajax({
url:"your url",
type:"get or post",
async:false,
dataType : "jsonp",
//服务端用于接收callback调用的function名的参数
jsonp:"callbackparam",
//callback的function名称
jsonpCallback:"success_jsonpCallback",
success:function(data){
console.log(data);
},
error:function(data){
console.log(data);
} });
两种方式的比较:
1、JSONP跨域方式支持各种较老的浏览器,但是缺点很明显,他只支持GET的方式提交,不支持其他Post的提交,Get方式对请求的参数长度有限制,在有些情况下可能不满足要求。(通过<script>标签中src属性获取js脚本,JSONP只支持GET是指浏览器在载入时加载<script src="http://url/balabala.js"/>时发送请求的方式是GET。或者说请求url中带的参数会在浏览器地址栏带出来。)
2、CORS使用起来简单,不需要客户端的额外处理,而且支持Post的方式提交请求,但是CORS的唯一一个缺点是对客户端的浏览器版本有要求。
3、直接采用nginx转发,性能好还能监控行为。