1、问题原因

实际项目开发中,我们经常前后端分离,前端代码工程与后端代码工程分别部署在不同的服务器上,然后这个时候再做前后端通信的时候就会出现跨域的情况。

这个操作分为两个部分,刚开始是前端发起对后端程序的访问,这个是可以操作的,并且后端程序也返回了response给前端,只是在浏览器的安全策略处理上不允许这类数据的接受。

这个主要是由于浏览器的同源策略的限制,现在所有支持JavaScript的浏览器基本都采用这种策略(注意是JavaScript才有同源策略 )。同源策略体现在三个方面:

(1)协议相同

(2)域名相同

(3)端口相同

例如下面的几个URL是否存在跨域问题:

http://www.a.com/a.js

http://www.a.com/b.js 

同一协议,同一域名,同一端口号 ,允许通信

http://www.a.com/a.js 

http://www.b.com/a.js  

同一协议,不同域名,同一端口号,不允许通信

http://www.a.com:8000/a.js

http://www.a.com/b.js  

同一协议,同一域名,不同端口 ,不允许通信

https://www.a.com/a.js 

http://www.a.com/b.js  

不同协议,同一域名,同一端口号,不允许通信

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转发,性能好还能监控行为。