新手学跨域之iframe
https://segmentfault.com/a/1190000000702539
页面嵌套iframe是比较常见的,比如QQ相关业务页面的登录框一般都是iframe的。使用ifrmae跨域要满足一个基本条件,父页面和子页面都是自己可以控制的,如果随便把iframe指向一个其他网站,想通过跨域手段操作它基本上是不可能的。
document.domain
document.domain是比较常用的跨域方法。实现最简单但只能用于同一个主域下不同子域之间的跨域请求,比如 foo.com 和 img.foo.com 之间,img1.foo.com 和 img2.foo.com 之间。只要把两个页面的document.domain都指向主域就可以了,比如document.domain='foo.com';。
设置好后父页面和子页面就可以像同一个域下两个页面之间访问了。父页面通过ifr.contentWindow就可以访问子页面的window,子页面通过parent.window或parent访问父页面的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的更多相关文章
- 如何实现跨域获取iframe子页面动态的url
有的时候iframe的子页面会动态的切换页面,我们在父页面通过iframe1.contentWindow.window.location只能获取同源的子页面的信息.获取跨域的子页面信息会报错. 这时可 ...
- JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)
这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...
- javascript跨域、iframe跨域访问
1.window 对象 浏览器会在其打开一个 HTML 文档时创建一个对应的 window 对象.但是,如果一个文档定义了一个或多个框架(即,包含一个或多个 frame 或 iframe 标签),浏览 ...
- JS跨域解决iframe高度自适应(IE8/Firefox/Chrome适用)
参考园友的js跨越实现,有提到三种方式: 1. 中间页代理方式,利用iframe的location.hash 参见:http://www.5icool.org/a/201203/a1129.html ...
- 设置跨域的iframe的高度
原因 如下图,A域中有个B域的页面,但是B的页面的长度不确定,A无法去设置一个准确的高度. PS:iframe高度设置auto是无效的 解决办法 如上图, (1)在B页面中加一个A的代理页面的ifra ...
- 允许CEF跨域访问iframe
默认情况下,如果嵌入本地Web页面,并在页面内部使用iframe来显示一个在线页面,加载的过程中会触发一个未捕获异常,虚函数CefV8ContextHandler::OnUncaughtExcepti ...
- 【转】JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)
这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...
- js实现跨域(jsonp, iframe+window.name, iframe+window.domain, iframe+window.postMessage)
一.浏览器同源策略 首先我们需要了解一下浏览器的同源策略,关于同源策略可以仔细看看知乎上的一个解释.传送门 总之:同协议,domain(或ip),同端口视为同一个域,一个域内的脚本仅仅具有本域内的权限 ...
- IFrame跨域访问&&IFrame跨域访问自定义高度
1.IFrame跨域访问: http://blog.csdn.net/fdipzone/article/details/17619673 2.IFrame跨域访问自定义高度: 由于JS禁止跨域访问,如 ...
随机推荐
- 常用原生JS方法总结(兼容性写法)
经常会用到原生JS来写前端...但是原生JS的一些方法在适应各个浏览器的时候写法有的也不怎么一样的... 今天下班有点累... 就来总结一下简单的东西吧…… 备注:一下的方法都是包裹在一个EventU ...
- 【Python五篇慢慢弹(4)】模块异常谈python
模块异常谈python 作者:白宁超 2016年10月10日12:08:31 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondo ...
- 计算机网络学习笔记--数据链据层之MAC子层(整理)
概述: 为什么需要介质访问控制子层(MAC)? 介质访问控制子层(MAC)是局域网体系结构中划分的子层,多路访问链路采用共享介质连接所有站点.发送站点通过广播方式发送数据并占用整个带宽,如果有多个站点 ...
- Cesium原理篇:Batch
通过之前的Material和Entity介绍,不知道你有没有发现,当我们需要添加一个rectangle时,有两种方式可供选择,我们可以直接添加到Scene的PrimitiveCollection,也可 ...
- 由css reset想到的深入理解margin及em的含义
由css reset想到的深入理解margin及em的含义 原文地址:http://www.ymblog.net/content_189.html 经常看到这样语句,*{ margin:0px;pad ...
- 代码的坏味道(8)——被拒绝的馈赠(Refused Bequest)
坏味道--被拒绝的馈赠(Refused Bequest) 特征 子类仅仅使用父类中的部分方法和属性.其他来自父类的馈赠成为了累赘. 问题原因 有些人仅仅是想重用超类中的部分代码而创建了子类.但实际上超 ...
- LinqToDB 源码分析——DataContext类
LinqToDB框架是一个轻量级的ORM框架.当然,功能上来讲一定比不上Entity Framework的强大.但是在使用上总让笔者感觉有一点Entity Framework的影子.笔者想过可能的原因 ...
- git 出错误“值对于Uint32太大或太小”
提交git代码的时候报的错误 这是因为修改的东西太少的原因,应该多修改一些就可以提交了 例如:只是删除了一个空格或者一个字符就提交git代码的话就会提示这个错误 解决方法:多多的改变一下代码,比如增加 ...
- 珍珠(bead)
题目描述 有n颗形状和大小都一致的珍珠,它们的重量都不相同.n为整数,所有的珍珠从1到n编号.你的任务是发现哪颗珍珠的重量刚好处于正中间,即在所有珍珠的重量中,该珍珠的重量列(n+1)/2位.下面给出 ...
- 基础总结之Activity
一.万事开头的序 网上看见大牛们的博客写的那样精彩,各种羡慕之情溢于言表.几次冲动均想效仿牛人写些博客来记录下自己的心得体会,但均无感亦或是感觉容易被喷,相信很多菜鸟和我一样都有过这样的担忧.万事开头 ...