- iframe页面之间嵌套,iframe页面在不在同一域名(什么是不同域),由于浏览器做安全限制,不允许跨域调用。
- 在HTML5之后提供了iframe之间通信方法,可以实现不同域之间传输数据。
子frame向顶端发送消息实现跨域方法调用:
- 子页面定义请求调用的方法列表 newTop ,这里测试子页面给top顶层页面发送消息
var newTop = {
setStatus : function(){
sendOrigin(arguments);
}
};
var originFunctionCallObject = {};// 缓存回调方法,接收其它iframe回调方法消息调用
//
var sendOrigin = function (_arguments){
// 解析调用方法中的参数(这里直接从调用方法的地方动态读取参数列表)
var _actionName = _arguments.callee.name;// 跨域调用的方法名称
// 定义传输对象数据
var _info = {
action : _actionName
};
for(var key in _arguments){
if (typeof _arguments[key] ==='function'){
// 回调函数缓存
originFunctionCallObject.f1=_arguments[key];
_info.fun = "f1";
}else {
_info [key] = _arguments[key];
}
}
// 给顶层frame发送消息请求
top.postMessage(_info, '*');
}
// 监听top页面发送的消息,执行回调方法逻辑处理
window.addEventListener('message', function(e){
console.info(e.data);
if (e.data.fun=='f1'){
originFunctionCallObject.f1();
}
}, false);
top页面中的定义监听,(这里没有做参数列表对应处理)
window.addEventListener('message', function(e){
var _source = e.source;// 跨域请求的对象源,
// 解析消息中的数据,组装方法参数
var _data = e.data;
var _keys = Object.keys(_data);
var args = [];
for(var k=0; k < _keys.length; k++){
var _value = _data[k+''];
if (_value != null){
args.push("'"+_value+"'");
}
}
// 调用本页面方法
call(_data.action,"("+args.join(",")+")");
// 给子frame发送消息
_source.postMessage(_data, "*");
}, false);
function call(functionName, arg){
eval("this."+functionName+arg);
}
// 是子页面需要调用的方法
function setStatus(){
alert("跨域请求调用success");
}