跨域请求

跨域请求一般用于请求第三方的数据,位于不同域的数据,一个数据多个域调用,自己用到的一般两种方法:

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 = '所请求的第三方域的页面';

posted @ 2011-02-17 11:59  xiaoxiaohui  阅读(1618)  评论(0编辑  收藏  举报