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

这时可以通过html5 提供的接口 postMessage来过去跨域子页面信息。如下代码:

在localhost:8000服务器下的入口测试页面:http://localhost:8000/index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 id="title"></h1>
<h1 id="title_1"></h1>
</body>
<script>
window.addEventListener('message',function(rs){
console.log(rs.data);
document.querySelector("#title").innerHTML = rs.data;
});
var iframe = document.createElement("iframe");
document.querySelector("body").appendChild(iframe);
iframe.setAttribute("src","http://localhost:3000/iframe.html");
//iframe.style.display = "none"; //利用contentWindow.window获取子页面地址
/*setTimeout(function () {
document.querySelector("#title_1").innerHTML = iframe.contentWindow.window.location;
},1000)*/
</script>
</html>

在localhost:3000服务器下的iframe页面:http://localhost:3000/iframe.html

这里页面会自动跳转到iframe_change.html

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h2>这是iframe里面的内容</h2>
</body>
<script>
window.location.href = "./iframe_change.html";
</script>
</html>

在localhost:3000服务器下的iframe_change页面:http://localhost:3000/iframe_change.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>iframe already changed</h2>
</body>
<script>
window.parent.postMessage(window.location.href,"*");
</script>
</html>

这里调用postMessage发送子页面信息。在index页面通过以下代码来获取子页面信息。

window.addEventListener('message',function(rs){
console.log(rs.data);
document.querySelector("#title").innerHTML = rs.data;
});

上面的跨域获取iframe动态url的方法可以实现一个微信web开发中一个很重要的问题:

主页面利用https://open.weixin.qq.com/connect/oauth2/authorize获取微信用户信息,主页面的域名是有限制的,需要在公众平台上配置而且一般配置成线上的域名。

但是在实际本地开发的时候,我们主页面的ip一般是localhost或者192.168.1.198:8080,这在微信浏览器上获取用户信息的时候会被拒绝,给开发调试造成极大的不便。

利用上面的iframe的方法就可以绕过域名限制的问题:将获取openId的功能交给单独的一个页面

getOpenId.html负责跳转到微信auth页面授权获取code:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>授权</title>
<script>
function getUrlParam(name){
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var r = window.location.search.substr(1).match(reg);
if (r != null) return decodeURIComponent(r[2].replace(/%20/g,"+")); return null;
} var companyAppId = "wx124345678"; //公司自己的appid
var wxCode = getUrlParam('code');
//如果url上没有code,则跳转授权
if(!wxCode){
var url = window.location.href;
window.location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?' +
'appid='+companyAppId+'&redirect_uri='+encodeURIComponent(url)+
'&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect';
}else {
//如果url上有code,则说明已经授权完毕可以返回code给主页面
window.parent.postMessage(wxCode,"*");
}
</script>
</head>
<body> </body>
</html>

getOpenId.js 在不影响文档流的情况下页面插入iframe进行微信授权,一旦获取到code,则移除iframe。

var wxTool = {
getOpenId:function (src,callback) {
var iframe = document.createElement("iframe");
iframe.style.display = "none";
document.querySelector("body").appendChild(iframe);
iframe.setAttribute("src",src); window.addEventListener('message',function(rs){
console.log(rs.data);
callback(rs.data);
iframe.remove();
});
}
};  

index.html

wxTool.getOpenId("http://live.domain.com/getOpenId.html",function (code) {
//TODO 利用code请求服务器 获取微信用户信息
})

  

总结:这种方法也许不是最快的,直接在入口页面的<head>下面写上<script>直接跳转进行微信授权然后重定向回来也许是最快的,但是一旦在跳转授权时由于网络原因可能导致页面会出现短暂的空白,这种情况用户是不愿看到的。而利用iframe的好处是它是异步的,不影响主业务的加载和运行。

所以如果你是希望在初始页面很快的呈现微信用户的信息则用上面第一种方法,否则,使用iframe可能更好些。

  

  

如何实现跨域获取iframe子页面动态的url的更多相关文章

  1. Js动态获取iframe子页面的高度////////////////////////zzzz

    Js动态获取iframe子页面的高度   Js动态获取iframe子页面的高度总结 问题的缘由 产品有个评论列表引用的是个iframe,高度不固定于是引发这个总结. 方法1:父级页面获取子级页面的高度 ...

  2. js 在iframe子页面获取父页面元素,或在父页面 获取iframe子页面的元素的几种方式

    用JS或jquery访问页面内的iframe,兼容IE/FF 注意:框架内的页面是不能跨域的! 假设有两个页面,在相同域下. index.html 文件内含有一个iframe: XML/HTML代码 ...

  3. Js获取iframe子页面全局变量

    项目中通过iframe内嵌了一个子页面,子页面定义了一些全局变量,父页面需要获取子页面的全局变量,做了一些测试(我的环境IE10和Firefox32.0.3),得出如下结论: IE下: window. ...

  4. iframe父页面获取iframe子页面的元素 与 iframe子页面获取父页面元素

    一.在iframe子页面获取父页面元素代码如下:$('#objld', parent.document); 二.在父页面获取iframe子页面的元素代码如下:$("#objid", ...

  5. 获取iframe子页面节点,响应浏览器宽高

    获取iframe子页面节点,响应浏览器宽高 html部分代码 <div> <iframe width="100%" height="100%" ...

  6. 获取iframe子页面内容高度给iframe动态设置高度

    <!DOCTYPE html><html> <head> <meta charset="UTF-8" /> <meta nam ...

  7. Js动态获取iframe子页面的高度总结

    问题的缘由 产品有个评论列表引用的是个iframe,高度不固定于是引发这个总结. 方法1:父级页面获取子级页面的高度 给元素设置高度 这方法是用在父级页面里的,通过获取子级页面的高度给iframe设置 ...

  8. Selenium_webdriver获取iframe子页面元素

    有时候我们在定位一个页面元素的时候发现一直定位不了,反复检查自己写的定位器没有任何问题,代码也没有任何问题.这时你就要看一下这个页面元素是否在一个iframe中,这可能就是找不到的原因之一.如果你在一 ...

  9. iframe子页面获取父页面元素的方法

    在iframe子页面获取父页面元素 代码如下: $.('#objld', parent.document); 在父页面获取iframe子页面的元素 代码如下: $("#objid" ...

随机推荐

  1. SharePoint 2013 文档库“样式”变了

    有朋友反馈说文档库的样式变了. 经查证,原来有人修改了视图的"样式":库设置—视图—样式,改为默认即可. 另外,如果编辑页面,编辑web部件的属性,在"杂项"勾 ...

  2. eclipse自动编译

    自动编译:对java应用没有什么意义,对web应用来说,当修改了代码时,会自动帮你编译并发布到web容器中去,省的重启web容器了. build:编译,Eclipse的编译是基于时间戳的判断机制的.c ...

  3. 一步步实现windows版ijkplayer系列文章之五——使用automake生成makefile

    一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...

  4. 解决Android SDK下载和更新失败问题

    今天更新sdk报错如下: Failed to fetch URL http://dl-ssl.google.com/android/repository/addons_list-1.xml. 说dl- ...

  5. android getActivity.findViewById获取ListView 返回NULL

    在控件ID正确的情况下,检查是否在实例化布局文件之后,获取LISTVIEW, 先inflate找layout下布局文件,并实例化后才能获得Listview的ID demo: public class ...

  6. Python-JS基础(基础结构~函数)

    程序本质上分为三大结构: 顺序结构.分支结构.循环结构JavaScript中的程序结构也是这样,下面我们来分别介绍JS中的三种基本程序结构:我们上篇博客中介绍到的使用逻辑运算符&&实现 ...

  7. Python-CSS高级 题目

    一.简答1.完整总结display三种基础显示方式的显示方式与嵌套规则 /* inline */ /*1.同行显示, 就相当于纯文本, 当一行显示不下, 如就是一个字显示不下,那么显示不下的那一个字就 ...

  8. Mac 安装 JDK

    1.访问Oracle官网 http://www.oracle.com,下载 JDK 2.安装JDK 解压 1 中下载的压缩包,在Finder下载目录中双击安装. 或者命令行安装,详见:http://w ...

  9. OCM_第十八天课程:Section8 —》RAC 数据库 _ RAC DB 搭建/RAC DB 配置使用

    注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...

  10. Myeclipse启动不了的解决方法

    Myeclipse启动不了的解决方法    我们在开发过程中经常在加载大工程时由于项目很大,导致编译时间很长.或是其他原因导致进度条有时候一直在不停地跑,占用了大量内存,在无奈之下直接将进程kill掉 ...