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. TortoiseGIT创建及合并分支

    一.创建分支 项目右键 => TortoiseGit(T) => 创建分支,然后右键切换到刚刚创建的分支,新增/修改一个文件,提交分支到远端服务器,推送成功之后分支就创建好了. 二.合并分 ...

  2. YYModel 源码解读(二)之YYClassInfo.h (3)

    前边3篇介绍了YYClassinfo 文件的组成单元,算是功能的分割,按照业务的设计思想来说,方向应该是相反的 由此引申出我们在设计api的思想其实和项目管理是很类似的----- 一些题外话 1.目的 ...

  3. Python(四)装饰器、迭代器&生成器、re正则表达式、字符串格式化

    本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解 ...

  4. HTML5 网络拓扑图整合 OpenLayers 实现 GIS 地图应用

    在前面<百度地图.ECharts整合HT for Web网络拓扑图应用>我们有介绍百度地图和 HT for Web 的整合,我们今天来谈谈 OpenLayers 和 HT for Web  ...

  5. 【原创】Kafka Consumer多线程实例

    Kafka 0.9版本开始推出了Java版本的consumer,优化了coordinator的设计以及摆脱了对zookeeper的依赖.社区最近也在探讨正式用这套consumer API替换Scala ...

  6. Live555流媒体服务器编译(Windows下)

    最近在回顾之前做过的相关项目,其中包括live555流媒体服务器相关,今天先把live555开源框架在Windows下的编译方法记录一下. live555是一套使用使用开放的标准协议(RTP/RTCP ...

  7. python学习笔记(基础二:注释、用户输入、格式化输出)

    注释 单行:# 多行:上下各用3个连续单引号或双引号 3个引号除了多行注释,还可以打印多行 举例: msg = ''' name = "Alex Li" name2 = name ...

  8. Java的Debug调试

    一.在项目上右键,Debug As>Debug on Server 二.在测试类上,Run As>Run On Server

  9. angular $http请求

    angular使用post.get向后台传参的问题 一.问题的来源 我们都知道向后台传参可以使用get.put,其形式就类似于name=jyy&id=001.但是在ng中我却发现使用$http ...

  10. 【前端构建】WebPack实例与前端性能优化

    计划把微信的文章也搬一份上来. 这篇主要介绍一下我在玩Webpack过程中的心得.通过实例介绍WebPack的安装,插件使用及加载策略.感受构建工具给前端优化工作带来的便利. 壹 | Fisrt 曾几 ...