跨域请求
跨域请求一般用于请求第三方的数据,位于不同域的数据,一个数据多个域调用,自己用到的一般两种方法:
1.jquery的JSONP
$.getJSOP(url+'?callback=?',function(data){})
用callback作为服务器端支持的标准jsonp参数,而每次执行这个方法都会用时间戳生成一个唯一的全局函数名,替换这个“?”,这个细节被封装到黑盒里,使用者不必了解,可以像普通的ajax请求一样,用匿名的回调函数作为最末尾的参数(这是jquery强调的风格),这种语法糖(syntactic sugar)的作用绝对不仅仅是让前端开发人员可以偷懒而已,对代码的可读性,兼容性和今后的维护都有好处。
2.iframe
iframe文件和所请求的数据应该在同一域中,文件请求同域下面的数据,然后引用这个文件的父页面调用iframe文件中的方法
1 window.TUI=window.$={}
2 TUI.get=function(url,fn){
3 var cro=document.getElementById("iframe");
4 if(cro){
5 cro.src=url
6 }
7 else{
8 var div=document.createElement('div')
9 div.innerHTML='<iframe src="'+url+'" frameborder="0" scrolling="0" allowtransparency="true" id="iframe"></iframe>'
10 }
11 document.body.appendChild(div.firstChild);
12 (function(){
13 document.getElementById("iframe").onload=function(){
14 document.getElementById("ifrmae").contentWindow.getData()
15 }
16 })()
17 }
18 $.get(url)
注:iframe父窗口与子窗口之间的通信
1.在父窗口中操作iframe页面的DOM
document.getElementById("frame").contentWindow.document...
window.frames['name']或window.frames[index].document....
IE6或IE7中可以使用document.frames['id']或document.frames['name'].get()
2.在子窗口中操作父窗口
parent:父窗口(如果当前窗口是顶级窗口则:top=parent=self)
top:顶级窗口(有好几层iframe时)
self:子身窗口相当于window
parent.document....(获取父级窗口的DOM)
3.获取跨域子页面的高度
例:a.html嵌套b.html,需要获取b页面的高度
不能通过document.getElementById('aa').contentWindow.document.documentElement.scrollHeight来获取高度,因为是跨域所以获取不到
思路:a(xx.com域名下面)嵌套b(oo.com域名下面),b页面嵌套c(xx.com域名下面),这样c页面就可以操作a页面的DOM和方法了,
b页面JS代码:
var height=document.documentElement.scrollHeight;
document.getElementById('bb').setAttribute('src','http://www.xx.com/c.html#'+height)
调用c页面,然后c页面中执行以下代码
function pushHei(){
var a=parent.parent.document.getElementById('aa')//因为c页面和a页面在同一个域
var href=window.location.hash.split("#")[1]+"px"
//var href=parent.parent.frames['aa'].frames['bb'].location//获取c页面的location,然后就可以得到b页面的高度,(主要一点是通过爷页面来获取父页面再来获取子页面的locationIE6不支持
}
pushHei()
4.跨域请求iframe解决方案
这里主要用到一个属性:window.name
需要注意以下两个点:
1.window.name 在同一个浏览器下面加载不同的页面依然存在的,例如在同一个浏览器窗口下面打开了a.html,在a.html中设置了window.name=data,关掉a.html页面,打开b页面,b页面中window.name依然等天data
2.window.name可以存取2M大小的东东
具体的例子:
var iframe1 = document.createElement("iframe");
iframe1.style.display = "none";
document.body.appendChild(iframe1);
(function () {
var same_domain = false;
// 当iframe加载完之后触发的函数
function iframe1_load() {
if (same_domain) {
// 取得从服务器返回的数据
alert(iframe1.contentWindow.name);
iframe1.contentWindow.close();
// 移除iframe1
document.body.removeChild(iframe1);
} else {
same_domain = true;
// 不能用iframe1.src = "empty.html",在IE下有错误
iframe1.contentWindow.location = "login.html";
}
}
// 在IE下要用attachEvent来添加iframe的onload处理函数
if (iframe1.attachEvent) {
iframe1.attachEvent("onload", function () {
iframe1_load();
});
}
else {
iframe1.onload = iframe1_load;
}
})();
iframe1.src = '所请求的第三方域的页面';