跨域的几种方式
目前了解的有五种方式
1、jsonp【get】大小有限制
2、document.domain只支持同一个域下不同子域跨域
3、form表单+document.name+iframe跨域【post+get】有兼容性问题,不兼容ie,谷歌
4、Flash URLLoader:【post+get】
5、Access-Control-Allow-Origin【post+get跨域】
下面来具体讲解每种跨域的方式
1、jsonp的原理是创建一个script标签来访问外域的js,jquery封装好了jsonp的跨域,例如:
1 $.ajax({ 2 url:'http://s.hc360.com:8080/search_mark/mark', 3 type:'get', 4 data:dataArr, 5 dataType:'jsonp', 6 jsonp:'callback', 7 jsonpCallback:'fn', 8 success:function(){ 9 10 } 11 })
请求的接口是:http://s.hc360.com:8080/search_mark/mark/?callback=fn;,dataType返回的必须是jsonp格式,否则会走到error里面,jsonp是跟后台约定的参数,默认是callback,jsonpCallback:是定义的回调函数的名字,默认jquery会随机生成一个名字;
2、修改document.domain,但是只适合在不同的子域名直接跨域;
如:map.baidu.com和www.baidu.com之间,把它们的document.domain="baidu.com"就可以通过js互相操作数据了。
3、form表单+document.name
在页面创建一个form和一个iframe,把form的action设置成要提交的url,target设置成ifram的name属性,method设置为提交方式
<form id="searchform" name="test_form" method="post" action="http://s.hc360.com:8080/search_mark/mark/" target="test_iframe"> <input type="hidden" name="content" value="name=jyy" /> </form> <iframe id="test_iframe" name="test_iframe" style="display:none"></iframe>
点击提交按钮的时候,把form里面的value设置成你要往后台传输的数据,然后执行form的submit事件。后端获取到数据后,设置window.name的值,并且一定要设置返回的数据类型是:
Content-Type:text/html;charset=utf-8;然后返回下面代码:
1 html><head></head><script>window.name='1';</script><body></body></html>
监听ifram的onload事件,让ifm跳转到一个空页面或者是当前域的页面,当跳转成功后,这个时候就不存在跨域问题了,就可以拿到后台返回的name值了,但是contentWindow有兼容性,在ie和谷歌里面获取的不是后台设置的值,这点要注意
1 var frm = $('#searchform'); 2 frm.find('input[name="content"]').val(valData); 3 frm.submit(); 4 var ifm = document.getElementById('test_iframe'); 5 var flag=0; 6 ifm.onload=function(){ 7 if(flag==0){ 8 flag=1; 9 this.contentWindow.location.href='about:blank'; 10 }else if(flag==1){ 11 var dataName = this.contentWindow.name; 12 alert(dataName); 13 } 14 };
4.flash跨域
1 <object id="swfhttprequest" class="hidden" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.adobe.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0"> 2 <param name="movie" value="swfhttprequest.swf?onload=setupSWFXHR" /> 3 <param name="allowScriptAccess" value="always" /> 4 <embed class="hidden" src="swfhttprequest.swf?onload=setupSWFXHR" allowScriptAccess="always" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"> 5 </embed> 6 </object>
在你要跨域的地方引入这段代码,里面的第一个param的value的值和embed的src是需要改变的,格式为:flash文件?onload=跨域的方法;
例如以上我的flash文件是swfhttprequest.swf是我的flash文件,setupSWFXHR是我的跨域方法如下面代码所示:
1 window.setupSWFXHR = function() { 2 var shr = new SWFHttpRequest(); 3 shr.open('GET', 'http://imgup.b2b.hc360.com/search_mark/mark/'); 4 shr.onreadystatechange = function() { 5 if (this.readyState != 4) return; 6 if (this.status == 200) { 7 // Success! Take appropriate action with this.responseText 8 } else { 9 // Oops - something went wrong 10 } 11 }; 12 shr.send('some=post&data=here'); 13 }
shr.open里面的第二个参数是要跨域的地址;这个方法是支持post和get跨域的。