有的时候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. 026_关于shell中的特殊变量$0 $n $* $@ $! $?

    一. $n:获取当前执行的shell脚本的第N个参数,n=1..9,当n为0时表示脚本的文件名,如果n大于9,用大括号括起来like${10}. $*:获取当前shell的所有参数,将所有的命令行参数 ...

  2. as 插件GsonFormat用法(json字符串快速生成javabean)

    GsonFormat 主要用于使用Gson库将JSONObject格式的String 解析成实体,该插件可以加快开发进度,使用非常方便,效率高. 插件地址:https://plugins.jetbra ...

  3. java多线程快速入门(十二)

    在静态方法上面加synchonizd用的是字节码文件锁 package com.cppdy; class MyThread8 implements Runnable { private static ...

  4. liunx rm 命令修改

    原文:https://blog.csdn.net/Ace_Shiyuan/article/details/60139791 1.打开一个终端,输入命令:vim ~/.bashrc Linux下修改rm ...

  5. cf 1041C双指针

    比赛的时候想着用单调队列做... 打完发现其实就是个双指针 /* 构造双指针解决即可 */ #include<iostream> #include<cstring> #incl ...

  6. python 全栈开发,Day25(复习,序列化模块json,pickle,shelve,hashlib模块)

    一.复习 反射 必须会 必须能看懂 必须知道在哪儿用 hasattr getattr setattr delattr内置方法 必须能看懂 能用尽量用__len__ len(obj)的结果依赖于obj. ...

  7. VS-常用的快捷键-总结

    1: 快速添加引用 === Shift+Alt+F10; 也可用于实现抽象类 2: 直接添加属性 ===prop+Tab+Tab; 3: 根据字段添加属性 === Ctrl +r+e; 4: 格式化代 ...

  8. hive遇到FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask错误

    hive遇到FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask错误 起因 ...

  9. myeclipse启动错误:org.eclipse.swt.SWTError: No more handles

    myeclipse启动错误,生成日志: !SESSION 2014-11-06 09:13:16.296 ----------------------------------------------- ...

  10. Android 倒计时按钮,倒计时发送短信验证码…

    Android基础之——CountDownTimer类,轻松实现倒计时功能https://www.cnblogs.com/yfceshi/p/6853746.html android中获取验证码后出现 ...