网络编程
位置:首页>> 网络编程>> JavaScript>> 也来谈谈”完美”跨域(2)

也来谈谈”完美”跨域(2)

作者:oldfish 来源:Alipay UED 发布时间:2008-12-19 12:34:00 

标签:跨域,javascript,浏览器,ie,firefox

方案五、JSONP

原理:有点脚本注入的味道

缺点:服务器端程序运行比脚本早,跨域交互时无法捕获前端页面元素的相关数据,比如自适应高度。

演示:[ 点此阅览 ]

在页面中添加如下代码,动态创建一个script,然后指定到子域的动态文件,在动态文件后面可以添加参数,在这里我加了一个回调函数,当请求返回后,会运行这个回调函数。

<script type="text/javascript"> 
function loadContent() 

 var scriptDom=document.createElement('script'); 
 var url = "http://www.lzdaily.com/domain/jsonp/Test.aspx?f=setDivContent'"; 
 scriptDom.src= url; 
 document.body.appendChild(scriptDom); 
}  
function setDivContent(love) 

 var fishDiv = document.getElementById("oldFish"); 
 fishDiv.innerHTML = love; 

</script>

在页面中添加如下代码,首先先取得主页面传过来的回调函数名,然后生成一段javascript代码,以回调函数带参数的形式返回主页面,这样就完成了跨域之间的通讯。由于服务器端程序执行总是优先于javascript代码,所以基本上没办法获取到子页面中DOM的相关数据,所以小白同学,我可以很负责人的告诉你,想通过这种方法实现跨域自适应高度是不可能的!

<script language="C#" runat="server"> 
void Page_Load(object sender, EventArgs e) 

  string f = Request.QueryString["f"]; 
  Response.Clear(); 
  Response.ContentType = "application/x-javascript"; 
  Response.Write(String.Format(@"{0}({1});", f,1122)); 
  Response.End(); 

</script>


 

方案六、window.name

原理:window.name本身并不能实现跨域,只是中间做了代理。

缺点:获取异域的前端页面元素值有一定局限性,比如取自适应高度的值。但是此方法在前端页面元素的数据交互上明显比JSONP强。

演示:[ 点此阅览 ]

这个方案,YAHOO的同事已经给出了详细的demo,我就不重复了,演示demo出自YAHOO克军之手。详细的说明可以参看“怿飞的BLOG”,个人觉得方案四比window.name适用面更广一些。

方案七、window.navigator

原理:window.navigator这个对象是在所有的Iframe中均可以访问的对象。应该是IE的一个漏洞!

缺点:不支持IE外的浏览器下的跨域。严格的dtd申明后,该方法失效!

演示:[ 点此阅览 ]

首先先申明一个Json用来保存所有页面的高度window.navigator.PagesHeight={”":0};,然后根据name的属性找到页面的数据window.navigator.getData,最后将页面的数据注册到window.navigator.PagesHeight中。这里还定义了一个函数resetIframeData,在页面加载的时候调用它,完成跨域的数据交互。注释中详细说明了参数的作用。

<script type="text/javascript"> 
window.navigator.PagesHeight={"":0};    
window.navigator.getData=function(pageName) {      
 return window.navigator.PagesHeight[pageName];   
};    
window.navigator.putData=function(pageName,pageHeight)  
{   
 window.navigator.PagesHeight[pageName]=pageHeight;   
};
/* 
*iframeId:页面中iframe的标识id 
*key:子页面自定义的json标识,这里就是子页面定义的"PortalData". 
*defaultData:无法取到值时候调用 
*/ 
function resetIframeData(iframeId,key,defualtData) 
{        
 var obj=document.getElementById(iframeId);   
 if(window.navigator.getData) 
 {   
  var pageHeight = window.navigator.getData(key);  
  if(pageHeight && String(pageHeight).match(/\d+/)) 
  {   
   obj.style.height=pageHeight+'px';   
  } 
  else 
  {   
   obj.style.height=defualtData + 'px';   
  }   
 } 
 else 
 {   
  obj.style.height=defualtData + 'px';   
 }      
}  
</script>

获取到页面高度后,将高度存到主页定义的Json中,Json标识为”PortalData”,这里可以自定义。

<script type="text/javascript"> 
window.onload = function getPageData() 
{          
 var pageHeight = document.body.scrollHeight;   
 if(window.navigator.putData) 
 { 
  window.navigator.putData("PortalData",pageHeight); 
 } 
}  
</script>

其实通过css也可以实现跨域,数据获取的实质其实就是动态载入一段CSS,然后解析其中的字段提取数据,这个方法比较“猥琐”,再这里就不多介绍了,当然flash也可以实现跨域,只是还没去实践,实践完了再补充。啥时候能补完呢?恩……

以上这么多方案,有可以“完美跨域”的吗?单一的看,我想没有吧,都有缺陷,但是只要不同情况下使用合适的方法,我想这才是最完美的!原来绕了一圈,我只是再说废话,哎!不论怎么样,还是希望这些废话对还在苦苦追求“完美”的同学们有所启发!

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com