有的时候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. web前端开发分享-css,js提高篇

    一. css基础知识掌握之后(个人的标准是:弄清块元素与内联元素的区别,弄清float的应用场景,弄清position[pə'zɪʃən] 下五个属性static['stætɪk],relative[ ...

  2. 温故而知新--JavaScript书摘(二)

    前言 毕业到入职腾讯已经差不多一年的时光了,接触了很多项目,也积累了很多实践经验,在处理问题的方式方法上有很大的提升.随着时间的增加,愈加发现基础知识的重要性,很多开发过程中遇到的问题都是由最基础的知 ...

  3. SeaJS入门教程系列之SeaJS介绍(一)

    前言SeaJS是一个遵循CommonJS规范的JavaScript模块加载框架,可以实现JavaScript的模块化开发及加载机制.与jQuery等JavaScript框架不同,SeaJS不会扩展封装 ...

  4. php单例模式的实例

    class Config1 {} class Config { * 必须先声明一个静态私有属性:用来保存当前类的实例 * 1. 为什么必须是静态的?因为静态成员属于类,并被类所有实例所共享 * 2. ...

  5. PHP中的一些常用函数

    <?php //===============================时间日期=============================== //y返回年最后两位,Y年四位数,m月份数字 ...

  6. CSS----布局注意事项

    1.当div标签中含有子标签,如果div标签的大小是被div中的子标签撑起来的,那么可能布局(之后)可能就会出现问题(if 父级div中没有border,padding,inlinecontent,子 ...

  7. Luogu P2426 【删数】

    状态定义: 一眼区间$DP$,从左右两边删不好定义状态,不如定义$dp[i][j]$表示$[i,j]$未删的最大值,转移就很自然了 转移: 从左边删$dp[i][j]=max(dp[i][j],dp[ ...

  8. 2017-2018-2 20155309 南皓芯 Exp7 网络欺诈防范

    实践内容 本实践的目标理解常用网络欺诈背后的原理,以提高防范意识,并提出具体防范方法.具体实践有 1,简单应用SET工具建立冒名网站 2.ettercap DNS spoof 3.结合应用两种技术,用 ...

  9. poj 2485 求最小生成树中 最长的一条边

    Sample Input 1 //T 3 //n0 990 692 //邻接矩阵990 0 179692 179 0Sample Output 692 prim # include <iostr ...

  10. centos6.9上mongdb安装

    一.设置yum源 vi /etc/yum.repos.d/mongodb.repo [mongodb-org-3.2] name=MongoDB Repository baseurl=https:// ...