iframe之间通信问题及iframe自适应高度问题 | 您所在的位置:网站首页 › iframe自适应高度 › iframe之间通信问题及iframe自适应高度问题 |
下面本人来谈谈iframe之间通信问题及iframe自适应高度问题。 1. iframe通信 分为:同域通信 和 跨域通信。所谓同域通信是指 http://localhost/demo/iframe/iframeA.html 下的a.html页面嵌套 iframe 比如: 的B.html页面,这两个页面数据进行通信,比如我想在父页面A.html 调用子页面当中的函数 我们很容易想到或者google下 document.getElementById('iframeA').contentWindow.b(); 这种方法,其中b 是子页面B.html中的一个函数。但是这样调用下有个问题我纠结了很久,就是既然在火狐下报这样的错误, 如下: 综合上面的思路 就可以写个这样的代码: topNddddddddddddddddame function A(){ alert("A"); } var iframe = document.getElementById('iframeA'); iframeIsLoad(iframe,function(){ var obj = document.getElementById('iframeA').contentWindow; obj.b(); }); function iframeIsLoad(iframe,callback){ if(iframe.attachEvent) { iframe.attachEvent('onload',function(){ callback && callback(); }); }else { iframe.onload = function(){ callback && callback(); } } }B.html 代码如下: var b = function(){ alert("B"); }2.子页面调用父页面的函数很简单,只要这样搞下就ok了,window.parent.A(); 3. 子页面取父页面元素的值: window.parent.document.getElementById("topName").innerHTML等方法。 二: iframe跨域通信。 iframe跨域访问一般分为2种情况,第一种是同主域,不同子域的跨域。 第二种是:不同主域跨域。 一、 是同主域下面,不同子域之间的跨域;可以通过document.domain 来设置相同的主域来解决。 假如现在我有个域 abc.example.com 下有个页面叫abc.html, 页面上嵌套了一个iframe 如下:,我想在abc域下的页面abc.html 访问 def域下的def.html 我们都知道由于安全性 游览器的同源策略的限制,js不能操作页面不同域下 不同协议下 不同端口的页面,所以就要解决跨域访问了,假如父页面abc.html 页面有个js函数:function test(){console.log(1);}; 我想在子页面调用这个函数 还是按照上面的同域方式调用 parent.test();这样,通过在火狐下看 已经跨域了 解决的办法是 在各个js函数顶部 加一句 document.domain = 'example.com',就可以解决了。abc.html代码如下: // 跨域 子页调用父页的 函数 (假设是下面test函数) document.domain = 'example.com'; function test(){console.log(1);};def.html代码如下: /* * 子页调用父页的方法 */ document.domain = 'example.com'; //window.top.test(); window.parent.test();还是这两个页面 我想父页调用子页 如下方法:a.html代码如下: /* * 跨域 父页想调用子页的的函数 */ document.domain = 'example.com'; var iframe = document.getElementById('iframe2'); iframeIsLoad(iframe,function(){ var obj = iframe.contentWindow; obj.child(); }); function iframeIsLoad(iframe,callback){ if(iframe.attachEvent) { iframe.attachEvent('onload',function(){ callback && callback(); }); }else { iframe.onload = function(){ callback && callback(); } } }假如现在def.html页面有个child函数 代码如下: document.domain = 'example.com'; function child(){console.log('我是子页');}就可以跨域调用了 不管是子页面调用父页面 还是父页面调用子页面。一切ok! 二、 是不同主域跨域; 虽然google有几种方法关于不同主域上的跨域问题 有通过location.hash方法或者window.name方法或者html5及flash等等,但是我觉得下面iframe这种方法值得学习下, 如下图所示:域a.com的页面request.html(即http://a.com/demo/ajax/ajaxproxy/request.html)里面嵌套了一个iframe指向域b.com(http://b.com/demo/ajax/ajaxproxy/response.html)的response.html,而response.html里又嵌套了域a.com的proxy.html。
思路:要实现a.com域下的request.html页面请求域b.com下的process.php,可以将请求参数通过url传给response.html,由response.html向process.php发起真正的ajax请求(response.html与process.php都属于域b.com),然后将返回的结果通过url传给proxy.html,最后由于proxy.html和request.html是在同个域下,所以可以在proxy.html利用window.top 将结果返回在request.html完成真正的跨域。
ok, 先看看页面结构 a.com域下有: request.html proxy.html b.com域下有: response.html process.php 先来看看request.html页面如下: New Document这里将会填上响应的结果 点击,发送跨域请求 document.getElementById('sendBtn').onclick = function() { var url = 'http://b.com/demo/ajax/ajaxproxy/reponse.html', fn = 'GetPerson', //这是定义在response.html的方法 reqdata = '{"id" : 24}', //这是请求的参数 callback = "CallBack"; //这是请求全过程完成后执行的回调函数,执行最后的动作 CrossRequest(url, fn, reqdata, callback); //发送请求 } function CrossRequest(url,fn,reqdata,callback) { var server = document.getElementById('serverIf'); server.src = url + '?fn=' +encodeURIComponent(fn) + "&data=" +encodeURIComponent(reqdata) + "&callback="+encodeURIComponent(callback); } //回调函数 function CallBack(data) { var str = "My name is " + data.name + ". I am a " + data.sex + ". I am " + data.age + " years old."; document.getElementById("result").innerHTML = str; }这个页面其实就是要告诉response.html:我要让你执行你定义好的方法GetPerson,并且要用我给你的参数'{"id" : 24}'。response.html纯粹是负责将CallBack这个方法名传递给下一位仁兄proxy.html,而proxy.html拿到了CallBack这个方法名就可以执行了,因为proxy.html和request.html是同域的。 response.html代码如下: New Document // 通用方法 ajax请求 function _request (reqdata,url,callback) { var xmlhttp; if(window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); }else { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange = function(){ if(xmlhttp.readyState == 4 && xmlhttp.status == 200) { var data = xmlhttp.responseText; callback(data); } } xmlhttp.open('POST',url); xmlhttp.setRequestHeader("Content-Type", "application/json; "); xmlhttp.send(reqdata); } // 通用方法 获取url参数 function _getQuery(key) { var query = location.href.split('?')[1], value = decodeURIComponent(query.split(key + "=")[1].split("&")[0]); return value; } //向process.php发送ajax请求 function GetPerson(reqdata,callback) { var url = 'http://b.com/demo/ajax/ajaxproxy/process.php'; var fn = function(data) { var proxy = document.getElementById('proxy'); proxy.src = "http://a.com/demo/ajax/ajaxproxy/Proxy.html?data=" + encodeURIComponent(data) + "&callback=" + encodeURIComponent(callback); }; _request(reqdata, url, fn); } (function(){ var fn = _getQuery('fn'), reqdata = _getQuery("data"), callback = _getQuery("callback"); eval(fn + "('" + reqdata +"', '" + callback + "')"); })();
这里其实就是接收来自request.html的请求得到请求参数和方法后向服务器process.php发出真正的ajax请求,然后将从服务器返回的数据以及从request.html传过来的回调函数名传递给proxy.html。 接下来看看php代码如下,其实就是想返回一个json数据: |
CopyRight 2018-2019 实验室设备网 版权所有 |