大家好,这里是小俊,第一次写博客,请大家多多指教!
说到JavaScript跨域,我首先想到的就是XMLHttpRequest2级了。
XHR2通过在HTTP响应中选择发送合适的CORS(跨域资源共享)允许跨域访问网站,实现CORS不需要做其他事情,只需要在open函数中传递url的时候传递的是一个跨域的地址,接下来我们看一下代码:
/*假设在域名http://abc.example.com下*/
var req = new XMLHttpRequest();
req.open('POST','http://www.example.com',true);
req.onreadystatechange = function(){
if (req.readyState == 4 && req.status == 200)
console.log('success');
};
req.onerror = function(){
console.log('err');
};
req.send(null);
上面例子很简单,当放松XMLHttpRequest请求的时候,HTTP信息头会附加一个额外的Origin的头部,在上面的例子中Oringin头部就是http://abc.example.com,如果服务器认为这个请求可以接受,就在HTTP信息头中的Access-Control-Allow-Origin回复相同的源信息(如果是公共资源,可能是回复”*”)。
整个过程大致是这样,注意如果在open方法中传递了用户和密码,那么不会通过跨域发送请求。
XHR2级IE8及以下不支持,那么可以用ie专有的XMLDomainRequest对象。
XDR对象很简单,使用跟XHR差不多,不多说直接看代码吧
var xdr = new XDomainRequest();
xdr.open("GET",'www.example.com');
xdr.onload = function(){
console.log(xdr.responseText);
};
xdr.onerror = function(){
console.log('err');
};
xdr.send(null);
接下来跟大家介绍第二中方法:利用iframe和document.domain实现跨域。这种方法只能在主域相同的不同子域之间的跨域。
document.domain记录着当前文档所在的域,这个属性可读/可写,可以通过修改它来西线跨域。话不多说来个栗子吃吃。
/*a.shuaibi.com*/
<iframe src="http://b.shuaibi.com/iframe-and-domain-b.html" id="ifr"></iframe>
<script>
console.log(document.domain);//a.shuaibi.com
document.domain = 'shuaibi.com';
var ifr = document.getElementById("ifr");
ifr.onload = function () {
console.log(ifr.contentWindow.bFun1());//没有设置domain时不允许访问,设置了domain返回b1的值
}
</script>
/*b.shuaibi.com/iframe-and-domain-b.html*/
<script>
document.domain = 'shuaibi.com';
var b1 = 'b1';
function bFun1 () {
return b1;
}
</script>
就这样,两个子域之间可以愉快的搞基了。
第三种方法:利用iframe和location.hash实现跨域
我们都知道hash嘛,修改它又不会刷新页面,所以我们就可以利用她来帮牛郎传递一下情书给织女。
在zhinv.com下的zhinv.html需要一个定时器来查看是否有新的来信(是否有hash的改变)
<iframe src="http://niulang.com/niulang.html"></iframe>
<script>
var nowHash = location.hash;
setInterval(function(){
if(location.hash != nowHash)
{
nowHash = location.hash;
console.log(nowHash);
}
},100);
</script>
大家都知道牛郎和织女只有在七月七才能见面,那谁来帮他们传递一下情书呢,这就需要一个信使了,这个信使在织女的后花园工作(zhinv.com/proxy.html)
<script>
parent.parent.location.hash = location.hash;
</script>
信使的任务很简单,就是把从牛郎那里得到的书信装到自己的口袋先(这个动作在niulang.html中完成),然后把书信交给织女(上述代码完成)
牛郎天天想着织女,哈哈
<script>
var b1 = 'b1';
//parent.location.hash = b1;//跨域,不能访问
var pro = document.createElement('iframe');
pro.src = 'http://zhinv.com/proxy.html#'+b1;//寄信
document.body.appendChild(pro);
</script>
到此,牛郎的书信安全到达织女手上。
第四种方法:利用window.name和iframe实现跨域
很简单,把数据放在iframe.contenWindow.name上,然后就可以获取了。
在b.com/b.html的代码,只需要把数据赋给window.name
<script>
window.name = 'bbbbb';
</script>
在这里我们依然需要一个代理,但是这次的代理什么都不做就可以了(哪里有这样的职业,我想说,请找我)
在a.com中新建一个proxy.html作为代理
a.com/a.html
<script>
var ifr = document.createElement('iframe');
ifr.src = 'http://b.com/b.html';
var st = 0;
ifr.onload = function () {
if (st == 0)
{
ifr.src = 'http://a.com/proxy.html';
st = 1;
}
else
{
console.log(ifr.contentWindow.name);//ifr.name和contentWindow.name是不同的
console.log(ifr.name);//空
}
};
document.body.appendChild(ifr);
</script>
修改iframe的src属性不会改变window对象,实现跨域。
当然除了上述的几种方法还有postMessage,jsonp等等,待我有空再来一波吧!
好了,终于写玩了,好累啊我需要休息,第一次写博客,如有错误请大家见谅。