您的位置:首页 > Web前端 > JavaScript

javascript 跨域问题解决办法总结

2014-01-07 22:47 423 查看

跨域的意思就是不同域名之间的页面默认是无法通信的。[b]因为浏览器默认是禁止跨域的;[/b]

图所示:chrome浏览器尝试获取mainFrame失败,提示DomException









1).假如你有个网站a.com中有个iframe的连接指向的是http://www.baidu.com,那么你想获取iframe中元素id为text1的值,通过js是无法获取到的。

办法:[b]location.hash,ifame[/b]

2).再换一种情况。a.a.com中有个iframe的src指向的是b.a.com,同家族a.com下的不同2级域名,在a.a.com中使用js也是无法获取到b.a.com中的内容。

办法:document.domain+iframe

下面是常用的解决跨域的办法

1..document.domain+iframe的设置

适用同一家族下的2个子域名a.a.com,b.a.com以及a.com,script.a.com

domain必须设置为a.com,及等于window.location.hostname

a.a.com想引用b.a.comhtml代码中的值

可以在a.a.com和b.a.com下面都加上伪域名a.com,接着在a.a.com中动态创建iframe

1)在b.b.com中加入

<scripttype=”text/javascript”>

document.domain="a.com";

</script>

2)接着在a.a.com中加入script代码,通过iframe的contextDocument获取b.a.com中的值

<scripttype=”text/javascript”>

document.domain='a.com';
varifr=document.createElement('iframe');
ifr.src='http://script.a.com/b.html';
ifr.style.display='none';
document.body.appendChild(ifr);
ifr.onload=function(){
vardoc=ifr.contentDocument||ifr.contentWindow.document;
//在这里操纵b.html
alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
};

</script>

a.a.com通过下面代码获取b.a.com窗口的高度

varh=window.navigator.userAgent.indexOf("MSIE")>0?document.body.scrollHeight:document.documentElement.scrollHeight;
parent.parent.document.getElementById('name').height=h;

两个不同的子域名伪装成了同域,完全在同源策略的保护下进行通信

2.location.hash,ifame(弊端:远端的数据页面,你要协调好,必须得放一段js)

可以解决不同主域名下的数据通信,但是hash有长度限制,数据暴露,数据类型有限制

子窗口无法改变无窗口的hash值,除非是同一域名下的

www.baidu.com#abc就是location.hash

假如a.com要使用b.com中的值。

1)首先a.com创建iframe,并指向b.com#parms

a.com用js定时检测iframe中src中的location.hash是否改变了,如果改变则获取其值则获取新location.hash值。

IE,chrome浏览器不支持跨域修改parent.location.hash值,所以需要代理。但是firefox支持修改。

a.com中的代码

<script>

functionstartRequest(){

varifr=document.createElement('iframe');

ifr.style.display='none';

ifr.src='http://www.cnblogs.com/lab/cscript/cs2.html#paramdo';//根据paramdo来决定获取啥值

document.body.appendChild(ifr);

}

//每2秒检测一次,是否变动了值

functioncheckHash(){

try{

vardata=location.hash?location.hash.substring(1):'';

if(console.log)//console.logjavascript中调试输出信息,比alert好

{

console.log('Nowthedatais'+data);

}

}catch(e){};

}

setInterval(checkHash,2000);

</script>

b.com页面的代码如下

//模拟一个简单的参数处理操作
switch(location.hash){
case'#paramdo':
callBack();
break;
case'#paramset':
//dosomething……
break;
}

//设置a.comiframesrc的location.hash
functioncallBack(){
try{

//此时是火狐正常执行
parent.location.hash='somedata';
}catch(e){
//iechrome的安全机制无法修改parent.location.hash,
//所以要利用一个中间的cnblogs域下的代理iframe
varifrproxy=document.createElement('iframe');
ifrproxy.style.display='none';
ifrproxy.src='http://a.com/test/cscript/cs3.html#somedata';//注意该文件在"a.com"域下
document.body.appendChild(ifrproxy);
}
}



a.com域名下cs3.html中的代码


//因为parent.parent和自身属于同一个域,所以可以改变其location.hash的值
parent.parent.location.hash=self.location.hash.substring(1);


3.window.name+ifame(弊端:远端的数据页面,你要协调好,必须得放一段js)

/article/5210715.html

总结:

location.hash在主页面a.com中设置'http://www.cnblogs.com/lab/cscript/cs2.html#paramdo'(#paramdo为location.hash,不会随页面刷新改变)。并在a.com页面js每隔一段时间就去检测#paramdo是否被改变了,如果被改变了,说明获取到数据了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: