有的时候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. saltstack自动化运维系列⑩SaltStack二次开发初探

    saltstack自动化运维系列⑩SaltStack二次开发初探 1.当salt运行在公网或者网络环境较差的条件下,需要配置timeout时间vim /etc/salt/master timeout: ...

  2. cacti系列(二)之cacti添加对tomcat服务器的监控

    cacti添加对tomcat的监控 1.首先下载监控tomcat的模板 TomcatStats-0.1.zip    2.导入模板 (cacti_host_template_tomcat_server ...

  3. centos6.7环境之kvm虚拟化quem工具配置及使用详解

    环境准备 需要勾选CPU的虚拟化支持,支持cpu虚拟化的CPU列表: intel支持虚拟化技术CPU列表: Intel 6 Cores / 12 Threads CPU Number: Code Na ...

  4. Android开源动画库nineoldandroids

    项目官网地址:http://nineoldandroids.com/ 使用这个库的原因是android3.0之后出了新的animation API,但是android3.0以下的不支持 这个库完成了这 ...

  5. Ex 3_17 无穷路径..._十一次作业

    (a) Inf(p)在p中出现了无穷多次,说明Inf(p)存在一个环当中,所以这个环的顶点肯定是某一个强连通部件的子集. (b) 若G中存在一条无穷路径,则G中至少存在一个环,且这个环至少有两个顶点, ...

  6. sklearn聚类模型:基于密度的DBSCAN;基于混合高斯模型的GMM

    1 sklearn聚类方法详解 2 对比不同聚类算法在不同数据集上的表现 3 用scikit-learn学习K-Means聚类 4 用scikit-learn学习DBSCAN聚类 (基于密度的聚类) ...

  7. Android 截屏与 WebView 长图分享经验总结

    最近在做新业务需求的同时,我们在 Android 上遇到了一些之前没有碰到过的问题,截屏分享. WebView 生成长图以及长图在各个分享渠道分享时图片模糊甚至分享失败等问题,在这过程中踩了很多坑,到 ...

  8. C++ Primer读书笔记(1)

    指针和引用 引用本身不是一个对象,因此不能定义引用的指针:而指针是一个对象,因此可以定义指针的引用. 此外,要理解一个复合类型的变量到底是什么类型,最简单的办法是从右向左阅读其定义,离变量名最近的符号 ...

  9. vmware+CentOs 6.9的安装步骤

    一.安装步骤 linux分区 登录用户名和密码 登录用户名和密码后安装成功 二.远程控制Xshell的安装

  10. poj1015 01二维背包

    /* 给定辩控双方给每个人的打分p[i],d[i], dp[j][k]表示前i个人有j个被选定,选定的人的辩控双方打分差之和是k,此状态下的最大辩控双方和 按01背包做,体积一维是1,体积二维是辩控双 ...