跨域方法

    • 跨域问题

    • 跨域的形成:主域、子域、ip和域名、协议不同、端口不同

    • 常用解决方案

      • iframe+document.domain:适用于垮子域的情况
        缺点是如果一个域名下存在安全问题,另一个域名下可能也会有问题,还有就是创建iframe的开销

      • 动态引入js脚本:适合所有的跨域场景
        引入的脚本会立刻执行,存在安全风险
        要与远端沟通约定变量,增加了开发和维护成本

      • iframe+location.hash:适合各种场景下跨域
        iframe嵌套引用,开销更大
        会产生历史记录,url中暴露传递的内容

      • iframe+window.name:使用iframe的window.name从外域传递数据到本地域,适合各种场景下跨域且数据安全
        缺点是数据有大小限制

      • postMessage跨域通讯页面域关系

      • 例子用hash跨域
      • 主页面a.html所属域A:www.taobao.com
        被iframe的页面b.html所属域B:www.alimama.com,假设地址:http://www.alimama.com/b.html

        实现效果

        A域名下的页面a.html中通过iframe嵌入B域名下的页面b.html,由于b.html的宽度和高度是不可预知而且会变化的,所以需要a.html中的iframe自适应大小.

        问题本质:

        js对跨域iframe访问问题,因为要控制a.html中iframe的高度和宽度就必须首先读取得到b.html的大小,A、B不属于同一个域,浏览器为了安全性考虑,使js跨域访问受限,读取不到b.html的高度和宽度.

        解决方案:

        引入代理代理页面c.html与a.html所属相同域A,c.html是A域下提供好的中间代理页面,假设c.html的地址:www.taobao.com/c.html,它负责读取location.hash里面的width和height的值,然后设置与它同域下的a.html中的iframe的宽度和高度.

        代码如下:

        a.html代码

        首先a.html中通过iframe引入了b.html
        <iframe id=”b_iframe” height=”0″ width=”0″ src=”http://www.alimama.com/b.html” frameborder=”no” border=”0px” marginwidth=”0″ marginheight=”0″ scrolling=”no” allowtransparency=”yes” ></iframe>

        b.html代码

        <script type=”text/javascript”>
          var b_width = Math.max(document.documentElement.clientWidth,document.body.clientWidth);
          var b_height = Math.max(document.documentElement.clientHeight,document.body.clientHeight);
          var c_iframe = document.getElementById(”c_iframe”);
          c_iframe.src = c_iframe.src+”#”+b_width+”|”+b_height; //http://www.taobao.com/c.html#width|height”
        }
        </script>
        <!–js读取b.html的宽和高,把读取到的宽和高设置到和a.html在同一个域的中间代理页面车c.html的src的hash里面–>
        <iframe id=”c_iframe”  height=”0″ width=”0″  src=”http://www.taobao.com/c.html” style=”display:none” ></iframe>

        c.html代码

        <script type=”text/javascript”>
        var b_iframe = parent.parent.document.getElementById(”b_iframe”);
        var hash_url = window.location.hash;
        var hash_width = hash_url.split(”#”)[1].split(”|”)[0]+”px”;
        var hash_height = hash_url.split(”#”)[1].split(”|”)[1]+”px”;
        b_iframe.style.width = hash_width;
        b_iframe.style.height = hash_height;
        </script>
        a.html中的iframe就可以自适应为b.html的宽和高了.

    • 看了园友的 window.name实现的跨域数据传输

      自己实践了一下,真的很好用。

      特将具体实现方法记录如下:

      如a.com网站想通过JS获取b.com网站的数据。

      1 在a.com网站添加一个空HTML页。名称为:http://a.com/null.html

      2 在a.com网站需要获取数据页面(如:http://a.com/getDomainData.html)内容如下:

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml" >
      <head>
          <title>跨域获取数据</title>
          <script type="text/javascript">
          function domainData(url, fn)
          {
      		var isFirst = true;
      		var iframe = document.createElement('iframe');
      		iframe.style.display = 'none';
      		var loadfn = function(){
      			if(isFirst){
      				iframe.contentWindow.location = 'http://a.com/null.html';
      				isFirst = false;
      			} else {
      				fn(iframe.contentWindow.name);
      				iframe.contentWindow.document.write('');
      				iframe.contentWindow.close();
      				document.body.removeChild(iframe);
      				iframe.src = '';
      				iframe = null;
      			}
      		};
      		iframe.src = url;
      		if(iframe.attachEvent){
      			iframe.attachEvent('onload', loadfn);
      		} else {
      			iframe.onload = loadfn;
      		}
      	    
      		document.body.appendChild(iframe);
          }
          </script>
      </head>
      <body>
      
      </body>
          <script type="text/javascript">
          domainData('http://b.com/data.html', function(data){
      		alert(data);
          });
          </script>
      </html>
      

      3 在b.com中添加获取数据页面 如:http://b.com/data.html 内容需包含:

       

      <script>
        window.name = '需要跨域传递的数据';
      </script>
      

      4 访问 http://a.com/getDomainData.html 就可返回 http://b.com/data.html 中的window.name中的数据了。

      需要注意的地方

      null.html 是必须的。内容可为空。

       iframe的onload事件绑定 必须这样写:

       

      if(iframe.attachEvent){
      	 iframe.attachEvent('onload', loadfn);
      } else {
      	 iframe.onload = loadfn;
      }
      

       

      调用domainData函数必须在body后面,或页面加载完后。

      调用时会执行 http://b.com/data.html 页面的脚本。

posted @ 2014-02-06 22:12  xiezhenzhong  阅读(189)  评论(0编辑  收藏  举报