出售域名 11365.com.cn
有需要请联系 16826375@qq.com
在手机上浏览
在手机上浏览

跨域消息通知postMessage

发布日期:2024-01-11

语法:otherWindow.postMessage(message, targetOrigin, [transfer]);
1、otherWindow:其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。

2、message:将要发送到其他 window的数据。它将会被结构化克隆算法序列化。这意味着你可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化。

3、targetOrigin:通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串"*"(表示无限制)或者一个URI。

 

对于跨域消息通知,一开始我是考虑使用websocket的,后来发现这个postMessage也能实现跨域通知,而且绝大数浏览器都支持,但是postMessage仅限于嵌套网页之间的消息交互,而websocket则不限制。

下面举个例子说明(已实现)
1)配置
主站配置可接收域

<add key="SingleOSS_Clients" value="http://localhost:8093,http://localhost:8099"/>

来自http://localhost:8093,http://localhost:8099的消息主站才会响应

子站(可多个)配置发送域

<add key="SingleOSS_Main" value="http://localhost"/>

子站的消息发送给主站http://localhost

2)嵌套子站 http://localhost:8093

//发送消息给主站,消息内容是一个对象{ type: "cmd", data: "user_logout" }
let singleOSS_Main = '@com.CTT.Common.ConfigPara.GetAppSettingValue("SingleOSS_Main")';
let user_no = '@(ViewBag.UserNo)';
if (singleOSS_Main != "" && user_no == "") {
    window.parent.postMessage({ type: "cmd", data: "user_logout" }, singleOSS_Main);
}

2)主站 http://localhost

//接收来自合法来源的消息
window.addEventListener("message", function (e) {
    try {
        if (e && e.data) {
            if ('@com.CTT.Common.ConfigPara.GetAppSettingValue("SingleOSS_Clients")'.split(',').indexOf(e.origin) != -1) { //是否消息来源合法
                if(e.data.type=="cmd" && e.data.data=="user_logout"){
                    top.location="/Account/Index";
                }
            }
        }
    } catch (ex) {
        console.error(ex);
    }
}, false);