一、需求iframe和父页面消息通信(Vue + Element UI项目 )
二、实现
基类plugin.postMessage.js
TypeScript
;
let SAFEORIGIN = process.env.VUE_APP_SAFE_ACCESS_ORIGIN;
let origin = "*";
let THAT;
let mark = [];
function __(args,origin){
if( window.top !== window.self ){
window.parent.postMessage( args , origin || "*");
}
};
function message(){
if( window ){
if( window.top === window.self ){
return THAT.prototype.$message.apply(THAT, arguments );
}else{
__( { __: 'post', __type: "message", args : [].slice.apply(arguments) } );
return Promise.resolve();
};
}
};
message.error = function(){
if( window ){
if( window.top === window.self ){
return THAT.prototype.$message.error.apply(THAT, arguments );
}else{
__( { __: 'post', __type: "error", args : [].slice.apply(arguments) } );
return Promise.resolve();
};
}
};
function confirm(){
if( window ){
if( window.top === window.self ){
return THAT.prototype.$confirm.apply(THAT, arguments );
}else{
let __time = btoa( ( new Date).valueOf() );
if( mark.indexOf( __time ) < 0 ){
mark= [__time ];
}else{
do{
__time += "1";
}while(mark.indexOf( __time ) >= 0 );
mark.push( __time )
}
return new Promise( (resolve,reject) => {
let _ = e => {
if( e.data && e.data["__"] ==="response" && e.data["__time"] === __time ){
if( e.data['__response'] === "resolve" ){
resolve( !0 )
}else{
reject( !1 );
}
window.removeEventListener( 'message' , _ );
}
}
window.addEventListener( 'message' , _ );
__( { __time, __: "request", __type: "confirm" , args : [].slice.apply(arguments) } );
});
}
}else{
return Promise.reject( new Error );
}
};
function testPostMessageSafe(){
let __time = btoa( ( new Date).valueOf() );
if( mark.indexOf( __time ) < 0 ){
mark= [__time ];
}else{
do{
__time += "1";
}while(mark.indexOf( __time ) >= 0 );
mark.push( __time )
}
return new Promise( ( resolve, reject ) => {
let _ = e => {
if( e && e.data && e.data[ "__time" ] === __time && e.data[ "__" ] === "response" && e.data[ "__response"] ==="test"){
origin = e.origin;
if( SAFEORIGIN && SAFEORIGIN.split(',').indexOf( origin ) > -1 ){
resolve( origin );
}else{
reject( -1 )
}
window.removeEventListener( "message" , _ );
}
}
window.addEventListener( "message" , _ );
__( { __: "request" , args , __time } );
})
};
function postDirect( directName, args, safe ){
if( safe ){
testPostMessageSafe().then(() => {
__({ __ : "direct", __direct: directName ,args, origin });
}).catch( ()=>{})
}else{
__( { __: "direct", __direct: directName , args } );
}
};
function sendMessage( args , safe ){
if( safe ){
testPostMessageSafe().then(() => {
__( { __: "post", args, origin } );
}).catch( ()=>{})
}else{
__({ __: "post", args });
}
};
function requestMessage( args,safe ){
if( window && window.top !== window.self ){
function req(){
let __time = btoa( ( new Date).valueOf() );
if( mark.indexOf( __time ) < 0 ){
mark= [__time ];
}else{
do{
__time += "1";
}while(mark.indexOf( __time ) >= 0 );
mark.push( __time )
}
return new Promise( ( resolve, reject ) => {
let _ = e => {
if( e && e.data && e.data[ "__time" ] === __time && e.data[ "__" ] === "response" ){
if( e.data[ "__response"] === "reject" ){
reject( e.data[ "args" ] )
}else{
resolve( e.data[ "args"] )
}
window.removeEventListener( "message" , _ );
}
}
window.addEventListener( "message" , _ );
__( { __: "request" , args , __time } );
})
};
if( safe ){
return testPostMessageSafe().then(() => {
return req();
})
}else{
return req();
}
}else{
return Promise.resolve();
}
};
export default function( v ){
THAT = v;
if( v ){
v.prototype.$$confirm = confirm; //向外抛出 element UI confirm 弹层 , 接收返回处理
v.prototype.$$message = message; // 向外抛出 element UI Message
v.prototype.$$postDirect = postDirect; //向外抛出带有事件名字的消息
v.prototype.$$sendMessage = sendMessage; //PostMessage
v.prototype.$$requestMessage = requestMessage; //向外请求带有参数消息,可接收返回值处理
v.prototype.$$__ = __;
}
}
iframe里发送消息给父页面
TypeScript
if( window.self !== window.top && !this.framelimit ){
this.$nextTick( ()=>{
this.$$postDirect("resize",document.body.scrollHeight)
})
}
父页面接收消息
window.addEventListener("message", this.__receiveMessage);