https://segmentfault.com/a/1190000000702539

页面嵌套iframe是比较常见的,比如QQ相关业务页面的登录框一般都是iframe的。使用ifrmae跨域要满足一个基本条件,父页面和子页面都是自己可以控制的,如果随便把iframe指向一个其他网站,想通过跨域手段操作它基本上是不可能的。

document.domain

document.domain是比较常用的跨域方法。实现最简单但只能用于同一个主域下不同子域之间的跨域请求,比如 foo.comimg.foo.com 之间,img1.foo.comimg2.foo.com 之间。只要把两个页面的document.domain都指向主域就可以了,比如document.domain='foo.com';
设置好后父页面和子页面就可以像同一个域下两个页面之间访问了。父页面通过ifr.contentWindow就可以访问子页面的window,子页面通过parent.windowparent访问父页面的window,接下来可以进一步获取dom和js。

<!-- foo.com/a.html -->
<iframe id="ifr" src="http://img.foo.com/b.html"></iframe>
<script>
document.domain = 'foo.com';
function aa(str) {
console.log(str);
}
window.onload = function () {
document.querySelector('#ifr').contentWindow.bb('aaa');
}
</script>
<!-- img.foo.com/b.html -->

<script>
document.domain = 'foo.com';
function bb(str) {
console.log(str);
} parent.aa('bbb');
</script>

window.name

只要不关闭浏览器,window.name可以在不同页面加载后依然保持。尝试在浏览器打开百度baidu.com,然后在控制台输入window.name='aaa';回车,接着在地址栏输入qq.com转到腾讯首页,打开控制台输入window.name查看它的值,可以看到输出了"aaa"
例如子页面bar.com/b.html向父页面foo.com/a.html传数据。

<!-- foo.com/a.html -->
<iframe id="ifr" src="http://bar.com/b.html"></iframe>
<script>
function callback(data) {
console.log(data)
}
</script>
<!-- bar.com/b.html -->
<input id="txt" type="text">
<input type="button" value="发送" onclick="send();"> <script>
var proxyA = 'http://foo.com/aa.html'; // foo.com下代理页面
var proxyB = 'http://bar.com/bb.html'; // bar.com下代理空页面 var ifr = document.createElement('iframe');
ifr.style.display = 'none';
document.body.appendChild(ifr); function send() {
ifr.src = proxyB;
} ifr.onload = function() {
ifr.contentWindow.name = document.querySelector('#txt').value;
ifr.src = proxyA;
}
</script>
<!-- foo.com/aa.html -->
top.callback(window.name)

location.hash

较常用,把传递的数据依附在url上
例如获取子页面bar.com/b.html的高度及其他数据

<!-- foo.com/a.html -->
<iframe id="ifr" src="http://bar.com/b.html"></iframe>
<script>
function callback(data) {
console.log(data)
}
</script>
<!-- bar.com/b.html -->
window.onload = function() {
var ifr = document.createElement('iframe');
ifr.style.display = 'none';
var height = document.documentElement.scrollHeight;
var data = '{"h":'+ height+', "json": {"a":1,"b":2}}';
ifr.src = 'http://foo.com/aa.html#' + data;
document.body.appendChild(ifr);
}
<!-- foo.com/aa.html -->
var data = JSON.parse(location.hash.substr(1));
top.document.getElementById('ifr').style.height = data.h + 'px';
top.callback(data);

window.navigator

IE6的bug,父页面和子页面都可以访问window.navigator这个对象,在navigator上添加属性或方法可以共享。因为现在没有IE6环境,这里就不写例子了。

postMessage

HTML5新增方法,现在浏览器及IE8+支持,简单易用高大上。

.postMessage(message, targetOrigin)参数说明

message: 是要发送的消息,类型为 String、Object (IE8、9 不支持)
targetOrigin: 是限定消息接收范围,不限制请使用 '*'

'message', function(e)回调函数第一个参数接收 Event 对象,有三个常用属性:

data: 消息
origin: 消息来源地址
source: 源 DOMWindow 对象

一个简单的父页面foo.com/a.html 和子页面 bar.com/b.html建立通信

<!-- foo.com/a.html -->
<iframe id="ifr" src="http://bar.com/b.html"></iframe>
<script>
window.onload = function () {
var ifr = document.querySelector('#ifr');
ifr.contentWindow.postMessage({a: 1}, '*');
}
window.addEventListener('message', function(e) {
console.log('bar say: '+e.data);
}, false);
</script>
<!-- bar.com/b.html -->
window.addEventListener('message', function(e){
console.log('foo say: ' + e.data.a);
e.source.postMessage('get', '*');
}, false)

新手学跨域之iframe的更多相关文章

  1. 如何实现跨域获取iframe子页面动态的url

    有的时候iframe的子页面会动态的切换页面,我们在父页面通过iframe1.contentWindow.window.location只能获取同源的子页面的信息.获取跨域的子页面信息会报错. 这时可 ...

  2. JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  3. javascript跨域、iframe跨域访问

    1.window 对象 浏览器会在其打开一个 HTML 文档时创建一个对应的 window 对象.但是,如果一个文档定义了一个或多个框架(即,包含一个或多个 frame 或 iframe 标签),浏览 ...

  4. JS跨域解决iframe高度自适应(IE8/Firefox/Chrome适用)

    参考园友的js跨越实现,有提到三种方式: 1. 中间页代理方式,利用iframe的location.hash 参见:http://www.5icool.org/a/201203/a1129.html ...

  5. 设置跨域的iframe的高度

    原因 如下图,A域中有个B域的页面,但是B的页面的长度不确定,A无法去设置一个准确的高度. PS:iframe高度设置auto是无效的 解决办法 如上图, (1)在B页面中加一个A的代理页面的ifra ...

  6. 允许CEF跨域访问iframe

    默认情况下,如果嵌入本地Web页面,并在页面内部使用iframe来显示一个在线页面,加载的过程中会触发一个未捕获异常,虚函数CefV8ContextHandler::OnUncaughtExcepti ...

  7. 【转】JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  8. js实现跨域(jsonp, iframe+window.name, iframe+window.domain, iframe+window.postMessage)

    一.浏览器同源策略 首先我们需要了解一下浏览器的同源策略,关于同源策略可以仔细看看知乎上的一个解释.传送门 总之:同协议,domain(或ip),同端口视为同一个域,一个域内的脚本仅仅具有本域内的权限 ...

  9. IFrame跨域访问&&IFrame跨域访问自定义高度

    1.IFrame跨域访问: http://blog.csdn.net/fdipzone/article/details/17619673 2.IFrame跨域访问自定义高度: 由于JS禁止跨域访问,如 ...

随机推荐

  1. ORACLE快速彻底Kill掉的会话

    在ORACLE数据库当中,有时候会使用ALTER SYSTEM KILL SESSION 'sid,serial#'杀掉一个会话进程,但是使用这个SQL语句杀掉会话后,数据库并不会立即释放掉相关的资源 ...

  2. (转)DOM appendHTML实现及insertAdjacentHTML

    appenChild() 原文转自 JS中有很多基本DOM方法,例如createElement, parentNode等,其中,appendChild方法是相当地常用与熟知,可谓是DOM节点方法中的& ...

  3. Install and Configure SharePoint 2013 Workflow

    这篇文章主要briefly introduce the Install and configure SharePoint 2013 Workflow. Microsoft 推出了新的Workflow ...

  4. 原生JS封装Ajax插件(同域&&jsonp跨域)

    抛出一个问题,其实所谓的熟悉原生JS,怎样的程度才是熟悉呢? 最近都在做原生JS熟悉的练习... 用原生Js封装了一个Ajax插件,引入一般的项目,传传数据,感觉还是可行的...简单说说思路,如有不正 ...

  5. Sublime Text 3 全程详细图文原创教程(持续更新中。。。)

    一. 前言 使用Sublime Text 也有几个年头了,版本也从2升级到3了,但犹如寒天饮冰水,冷暖尽自知.最初也是不知道从何下手,满世界地查找资料,但能查阅到的资料,苦于它们的零碎.片面,不够系统 ...

  6. Python笔记之不可不练

    如果您已经有了一定的Python编程基础,那么本文就是为您的编程能力锦上添花,如果您刚刚开始对Python有一点点兴趣,不怕,Python的重点基础知识已经总结在博文<Python笔记之不可不知 ...

  7. CSS知识总结(三)

    CSS的常用样式 1.字体样式 1)字体名称(font-family) font-family  :  <family-name> 设置文字名称,可以使用多个名称,或者使用逗号分隔,浏览器 ...

  8. PyQt4入门学习笔记(四)

    在PyQt4中的事件和信号 事件 所有的GUI应用都是事件驱动的.事件主要是来自于应用的使用者,但是像互联网连接,窗口管理器或者计时器也可以产生事件.当我们调用应用的exec_()方法时,应用就进入了 ...

  9. 百度EChart3初体验

    由于项目需要在首页搞一个订单数量的走势图,经过多方查找,体验,感觉ECharts不错,封装的很细,我们只需要看自己需要那种类型的图表,搞定好自己的json数据就OK.至于说如何体现出来,官网的教程很详 ...

  10. jQuery中取消后续执行的内容

    <html xmlns="http://www.w3.org/1999/xhtml"><head>    <title></title&g ...