Javascript与iframe的那些事儿

iframe 很多网站都在用,虽然方便开发与维护(可能同时有几个页面调用同一个  iframe  ),不过却存在安全问题。嵌入  iframe  的页面,父页面与子页面均可以很轻松的在同域或跨子域的情况下进行读写操作;在完全不同域的情况下,也可以通过更改  hash  的方式进行通信。下面我在九个不同(版本的)浏览器中对此进行数据传输与更改的兼容性测试。

同域或跨子域读写操作 iframe 里的内容

父页面读写操作子页面:

[javascript]  view plain copy
  1. <iframe id="test-iframe" name="test-iframe" src="child.html" scrolling="no" frameborder="0"></iframe>  
  2.   
  3. <script>  
  4. window.onload = function () {  
  5.   /* 
  6.    *  下面两种获取节点内容的方式都可以。 
  7.    *  由于 IE6, IE7 不支持 contentDocument 属性,所以此处用了通用的 
  8.    *  window.frames["iframe Name"] or window.frames[index] 
  9.    */  
  10.   var d = window.frames["test-iframe"].document;  
  11.   d.getElementsByTagName('h1')[0].innerHTML = 'pp';  
  12.   alert(d.getElementsByTagName('h1')[0].firstChild.data);  
  13. }  
  14. </script>  

注:在请务必通过 window.onload 方法访问 iframe 中的节点,否则浏览器会提示错误-拒绝访问。在 IE8, Firefox3.6, Opera11 下在DOMReady 时也可以访问 iframe 中的节点。

子页面读写操作父页面:

[javascript]  view plain copy
  1. <script>  
  2.   parent.document.getElementsByTagName('h1')[0].innerHTML = 'pp';  
  3.   alert(parent.document.getElementsByTagName('h1')[0].firstChild.data);  
  4. </script>  

小结:

  • 1 测试通过 IE6, IE7, IE8, Firefox2.0, Firefox3.0, Firefox3.6, Chrome8, Opera11, Safari5.
  • 2 查阅资料得出 document.getElementById(‘id name’).contentDocument 全等于 window.frames["iframe Name"].document.
  • 3 跨子域时,需要在父页面和子页面 JS 中分别加上 document.domain = 'xxx.com';

跨域操作 iframe 里内容

当两个网页所在域不同时,要实现数据的互相调用,只能通过 JS 改变 location 对象的 hash 属性的值来做到互相通信。

父页面:

[javascript]  view plain copy
  1. <iframe id="test-iframe" src="http://www.yyy.com/child.html" scrolling="no" frameborder="0"></iframe>  
  2. <input type="button" value="send" οnclick="sendRequest()" />  
  3.   
  4. <script>  
  5.   
  6. function sendRequest() {  
  7.   document.getElementById('test-iframe').src += '#a';  
  8. }  
  9.   
  10. var interval = window.setInterval(function(){  
  11.   if(location.hash) {  
  12.     alert(location.hash);  
  13.     window.clearInterval(interval);  
  14.   }  
  15. },1000);  
  16.   
  17. </script>  

子页面:

[javascript]  view plain copy
  1. <h1>RRRRRR</h1>  
  2.   
  3. <script>  
  4. var url = 'http://www.xxx.com/father.html';  
  5.     oldHash = self.location.hash,  
  6.     newHash,  
  7.     interval = window.setInterval(function(){  
  8.         newHash = self.location.hash;  
  9.         if(oldHash != self.location.hash) {  
  10.         document.getElementsByTagName('h1')[0].innerHTML = 'pp';  
  11.         //alert(parent.location.href); //去掉这个注释,浏览器会提示无权限  
  12.         parent.location.href = url + '#b';  
  13.           window.clearInterval(interval);  
  14.         }  
  15.     },500);  
  16. </script>  

小结:

  • 1 经测试 IE6, IE7, IE8, Firefox2.0, Firefox3.0, Firefox3.6, Chrome8, Opera11, Safari5, 除 IE6, IE7 外只要改变hash 就会记录在浏览器 history中。
  • 2 我有试图在子页面用 parent.location.replace 的方法来避免父页面向服务器发送请求而进行跳转,这样理论上浏览器就不会记录历史,但未能奏效。
  • 2 子页面无权读取父页面的 url, 但可以对父页面的 url 进行写操作,所以跨域操作时,要提前得知父页面的url

由于前端解决跨域问题的局限性比较大,所以最好用 服务器端解决方案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值