zoukankan      html  css  js  c++  java
  • JS iframe 跨域

     转自:wujiajun1020

    方案一、剪贴板

    原理:IE本身依附于windows平台的特性为我们提供了一种基于iframe,利用内存来“绕行”的方案,在这里我称之为,本地存储原理。

    缺点:不支持非IE浏览器,并且影响到用户对剪贴板的操作,用户体验非常不好,特别是在IE7下,受安全等级影响,会弹出提示框。


    子页面在子域:demo.ioldfish.cn下,在页面中加入如下代码获取页面高度并存入剪贴板。

    1. <script type="text/javascript">
    2. var ua = navigator.userAgent;
    3. if ((i = ua.indexOf("MSIE")) >= 0) 
    4. {
    5.  var iObjH = window.document.documentElement.scrollHeight;
    6.  window.clipboardData.setData('text',String(iObjH));
    7. }
    8. </script>

    主页面在主域:www.ioldfish.cn下,在页面中加入如下代码,获取剪贴板的值并赋值为子页面所在的iframe的高度。

    1. <script type="text/javascript">
    2. window.onload = function()
    3. {
    4.  var iObj =document.getElementById('iId');
    5.  iObj.style.height=parseInt(window.clipboardData.getData('text'))+'px';
    6. }
    7. </script>

     

    方案二、document.domain

    原理:设置了document.domain,欺骗浏览器

    缺点:无法实现不同主域之间的通讯。并且当在一个页面中还包含有其它的iframe时,会产生安全性异常,拒绝访问。

     

    主页面在主域:www.ioldfish.cn下,子页面在子域:demo.ioldfish.cn下,在两个页面的头部都加入如下代码:

    1. <script type="text/javascript">
    2.  document.domain="ioldfish.cn";
    3. </script>

    方案三、通过JS获取hash值实现通讯

    原理:hash可以实现跨域传值实现跨域通讯。

    缺点:对于父窗口URL参数动态生成的,处理过程比较复杂一些。并且IE之外的浏览器遇到hash的改变会记录历史,影响浏览器的前进后退功能,体验不佳。


    子页面在主域:www.lzdaily.com下,在页面中添加如下代码,因为hash是不受跨域限制的,所以可以将本页面的高度顺利的传送给主页面的hash。

    1. <script type="text/javascript">
    2.  var hashH = document.documentElement.scrollHeight;
    3.  var urlA = "http://www.ioldfish.cn/wp-content/demo/domain/hash/a2.html";
    4.  parent.location.hrefurlA+"#"+hashH;
    5. </script>

    主页面在主域:www.ioldfish.cn下,在页面中添加如下代码,首先取得子页面传递过来的hash值,然后将hash值赋到子页面所在的iframe的高度上。

    1. <script type="text/javascript">
    2. window.onload = function()
    3. {
    4.  var iObj = document.getElementById('iId');
    5.  if(location.hash)
    6.  {
    7.   iObj.style.height=location.hash.split("#")[1]+"px";
    8.  }
    9. }
    10. </script>

    方案四、传hash值实现通讯改良版

    原理:该方案通过“前端代理”的方式,实现hash的传值,体验上比之方案三有了很大的提升。

    缺点:对于父窗口URL参数动态生成的,处理过程比较复杂一些。

     

    子页面在主域:www.lzdaily.com下,在页面中添加如下代码,首先在页面里添加一个和主页面同域的iframe[也可动态生成],他的作用就像是个跳板。C页面中不需任何代码,只要确保有个页面就防止404错误就可以了!该方法通过修改iframe的name值同样可以跨域传值,只是比较”猥琐“而已。

    1. <iframe id="iframeC" name="iframeC" src="http://www.ioldfish.cn/wp-content/demo/domain/hashbetter/c.html" frameborder="0" height="0"></iframe>

    然后在页面中加上如下代码,利用页面C的URL接收hash值,并负责把hash值传给同域下的主页面。

    1. <script type="text/javascript">
    2.  hashH = document.documentElement.scrollHeight;
    3.  urlC = "http://www.ioldfish.cn/wp-content/demo/domain/hashbetter/c.html";
    4.  document.getElementById("iframeC").src=urlC+"#"+hashH;
    5. </script>

    主页面在主域:www.ioldfish.cn下,在页面中添加如下代码,获取从C页面中传递过来的hash值。这里应用到一个技巧,就是直接从A页面用frames["iId"].frames["iframeC"].location.hash,可以直接访问并获取C页面的hash值。这样一来,通过代理页面传递hash值,比起方案三,大大提高了用户体验。

    1. <script type="text/javascript">
    2. window.onload = function()
    3. {
    4.  var iObj = document.getElementById('iId');
    5.  iObjH = frames["iId"].frames["iframeC"].location.hash;
    6.  iObj.style.height = iObjH.split("#")[1]+"px";
    7. }
    8. </script>

    方案五、JSONP

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

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


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

    1. <script type="text/javascript">
    2. function loadContent()
    3. {
    4.  var scriptDom=document.createElement('script');
    5.  var url = "http://www.lzdaily.com/domain/jsonp/Test.aspx?f=setDivContent'";
    6.  scriptDom.src= url;
    7.  document.body.appendChild(scriptDom);
    8. } 
    9. function setDivContent(love)
    10. {
    11.  var fishDiv = document.getElementById("oldFish");
    12.  fishDiv.innerHTML = love;
    13. }
    14. </script>

    子页面在主域:www.lzdaily.com下,在页面中添加如下代码,首先先取得主页面传过来的回调函数名,然后生成一段 javascript代码,以回

    调函数带参数的形式返回主页面,这样就完成了跨域之间的通讯。由于服务器端程序执行总是优先于javascript代码,所以基本上没办法获取

    到子页面中DOM的相关数据,所以小白同学,我可以很负责人的告诉你,想通过这种方法实现跨域自适应高度是不可能的!

    1. <script language="C#" runat="server">
    2. void Page_Load(object sender, EventArgs e)
    3. {
    4.   string f = Request.QueryString["f"];
    5.   Response.Clear();
    6.   Response.ContentType = "application/x-javascript";
    7.   Response.Write(String.Format(@"{0}({1});", f,1122));
    8.   Response.End();
    9. }
    10. </script>

    方案六、window.name

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

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

    这个方案,YAHOO的同事已经给出了详细的demo,我就不重复了,演示demo出自YAHOO克军之手。详细的说明可以参看“怿飞的BLOG”,个人觉

    得方案四比window.name适用面更广一些。


    方案七、window.navigator

    原理:window.navigator这个对象是在所有的Iframe中均可以访问的对象。应该是IE的一个漏洞!
    缺点:不支持IE外的浏览器下的跨域。严格的dtd申明后,该方法失效!

    主页面在主域:www.ioldfish.cn下,首先先申明一个Json用来保存所有页面的高度window.navigator.PagesHeight={”":0};,然后根据name

    的属性找到页面的数据window.navigator.getData,最后将页面的数据注册到window.navigator.PagesHeight中。这里还定义了一个函数

    resetIframeData,在页面加载的时候调用它,完成跨域的数据交互。注释中详细说明了参数的作用。

    1. <script type="text/javascript">
    2. window.navigator.PagesHeight={"":0};   
    3. window.navigator.getData=function(pageName) {     
    4.  return window.navigator.PagesHeight[pageName];  
    5. };   
    6. window.navigator.putData=function(pageName,pageHeight) 
    7. {  
    8.  window.navigator.PagesHeight[pageName]=pageHeight;  
    9. };

    1. /*
    2. *iframeId:页面中iframe的标识id
    3. *key:子页面自定义的json标识,这里就是子页面定义的"PortalData".
    4. *defaultData:无法取到值时候调用
    5. */
    6. function resetIframeData(iframeId,key,defualtData)
    7. {       
    8.  var obj=document.getElementById(iframeId);  
    9.  if(window.navigator.getData)
    10.  {  
    11.   var pageHeight = window.navigator.getData(key); 
    12.   if(pageHeight && String(pageHeight).match(/\d+/))
    13.   {  
    14.    obj.style.height=pageHeight+'px';  
    15.   }
    16.   else
    17.   {  
    18.    obj.style.height=defualtData + 'px';  
    19.   }  
    20.  }
    21.  else
    22.  {  
    23.   obj.style.height=defualtData + 'px';  
    24.  }     
    25. } 
    26. </script>

    子页面在主域:www.lzdaily.com下,获取到页面高度后,将高度存到主页定义的Json中,Json标识为”PortalData”,这里可以自定义。

    1. <script type="text/javascript">
    2. window.onload = function getPageData()
    3. {         
    4.  var pageHeight = document.body.scrollHeight;  
    5.  if(window.navigator.putData)
    6.  {
    7.   window.navigator.putData("PortalData",pageHeight);
    8.  }
    9. } 
    10. </script>

    其实通过css也可以实现跨域,数据获取的实质其实就是动态载入一段CSS,然后解析其中的字段提取数据,这个方法比较“猥琐”,再这里就

    不多介绍了

    知识共享许可协议
    作品Tim Zhang创作,采用知识共享署名 3.0 中国大陆许可协议进行许可。 。
  • 相关阅读:
    Top 10 Product Manager Skills To Boost Your Resume In 2021
    大数据知识梳理
    B端产品如何设计权限系统?
    华三盒式交换机MAC、ARP、Route性能表项参数查询
    中了传说中的挖矿病毒
    SqlServer 2019 事务日志传送
    docker中生成的pdf中文是方框的解决方案
    The Live Editor is unable to run in the current system configuration
    2021 面试题大纲
    五分钟搞定Docker安装ElasticSearch
  • 原文地址:https://www.cnblogs.com/ccdc/p/2275608.html
Copyright © 2011-2022 走看看