为什么 JavaScript "window.postMessage" 创建重复消息?
Why does JavaScript "window.postMessage" create duplicate messages?
我正在尝试打开一个弹出窗口 window,做一些事情,然后将消息发送回开头 window 这样我就可以用它发送的数据做更多事情。
本质上,我正在改编the process outlined here。
这是我关于“开场window”的代码。单击社交连接按钮时 运行s。该代码打开一个弹出窗口 window 并在打开 window 时分配一个侦听器事件以接收来自弹出窗口的消息:
//Do the operation
let windowObjectReference = null;
let previousUrl = null;
const openSignInWindow = (url, name) => {
// remove any existing event listeners
window.removeEventListener('message', receiveMessage);
// window features
const strWindowFeatures =
'toolbar=no, menubar=no, width=600, height=700, top=100, left=100';
if (windowObjectReference === null || windowObjectReference.closed) {
/* if the pointer to the window object in memory does not exist
or if such pointer exists but the window was closed */
windowObjectReference = window.open(url, name, strWindowFeatures);
} else if (previousUrl !== url) {
/* if the resource to load is different,
then we load it in the already opened secondary window and then
we bring such window back on top/in front of its parent window. */
windowObjectReference = window.open(url, name, strWindowFeatures);
windowObjectReference.focus();
} else {
/* else the window reference must exist and the window
is not closed; therefore, we can bring it back on top of any other
window with the focus() method. There would be no need to re-create
the window or to reload the referenced resource. */
windowObjectReference.focus();
}
// add the listener for receiving a message from the popup
window.addEventListener('message', event => receiveMessage(event), false);
// assign the previous URL
previousUrl = url;
};
const receiveMessage = event => {
// Do we trust the sender of this message? (might be different from what we originally opened, for example).
if (event.origin !== websiteHomeUrlNoSlash) {
return;
}
const { data } = event;
console.log(data); //<--- THIS WHERE I'm SEEING DUPLICATES
};
//Invoke the function
openSignInWindow(url, name);
在弹出窗口中,用户登录到他们的社交帐户,然后被重定向到我的应用程序上的一个页面,下面的代码是 运行。该代码将一条消息发回到开头 window,然后关闭弹出窗口:
// Get the message data
const messageObj = {
pluginReason: pluginReasonVar,
displayName: displayNameVar,
provider: providerVar,
};
if (window.opener) {
// send them to the opening window
window.opener.postMessage(messageObj, websiteHomeUrlNoSlash);
// close the popup
if (closePopup) {
window.close();
}
}
一切几乎都按预期工作。用户可以登录他们的社交帐户,所有重定向和弹出窗口的打开和关闭都可以正常工作。
问题:
如果用户在不刷新页面的情况下多次执行 Social Connect 过程,则打印到控制台的消息数据会越来越重复 运行。
例如:
- 1号运行打印一次
console.log(data)
。到目前为止,这按预期工作。
- 2号运行
console.log(data)
打印两次。它应该只打印一次。
- 3号运行
console.log(data)
打印三遍。它应该只打印一次。
Social Connect 进程每次 运行 都应该只打印一次。但不知何故,它在每个后续 运行.
上添加了一个副本
这种重复不断增加,直到用户刷新页面,从一开始倒计时。
我想在 console.log(data)
点做更多的数据操作,但是当它在每个后续 运行.
上创建重复副本时我不能这样做
如何阻止这种情况发生?
可能是监听事件没有分离?如果是这样,我该如何解决?
您已经创建了一个匿名方法 (event) => { }
作为包装器并将其附加到 addEventListener
方法。
window.addEventListener('message', event => receiveMessage(event), false);
无法删除
window.removeEventListener('message', receiveMessage);
要修复它,请进行如下更改:
window.addEventListener('message', receiveMessage, false);
同时,如果方法receiveMessage
在每次关闭window时都丢失,最好将removeEventListener
部分移到receiveMessage
中。
const receiveMessage = (event)=> {
window.removeEventListener('message', receiveMessage);
// do something else
}
我正在尝试打开一个弹出窗口 window,做一些事情,然后将消息发送回开头 window 这样我就可以用它发送的数据做更多事情。
本质上,我正在改编the process outlined here。
这是我关于“开场window”的代码。单击社交连接按钮时 运行s。该代码打开一个弹出窗口 window 并在打开 window 时分配一个侦听器事件以接收来自弹出窗口的消息:
//Do the operation
let windowObjectReference = null;
let previousUrl = null;
const openSignInWindow = (url, name) => {
// remove any existing event listeners
window.removeEventListener('message', receiveMessage);
// window features
const strWindowFeatures =
'toolbar=no, menubar=no, width=600, height=700, top=100, left=100';
if (windowObjectReference === null || windowObjectReference.closed) {
/* if the pointer to the window object in memory does not exist
or if such pointer exists but the window was closed */
windowObjectReference = window.open(url, name, strWindowFeatures);
} else if (previousUrl !== url) {
/* if the resource to load is different,
then we load it in the already opened secondary window and then
we bring such window back on top/in front of its parent window. */
windowObjectReference = window.open(url, name, strWindowFeatures);
windowObjectReference.focus();
} else {
/* else the window reference must exist and the window
is not closed; therefore, we can bring it back on top of any other
window with the focus() method. There would be no need to re-create
the window or to reload the referenced resource. */
windowObjectReference.focus();
}
// add the listener for receiving a message from the popup
window.addEventListener('message', event => receiveMessage(event), false);
// assign the previous URL
previousUrl = url;
};
const receiveMessage = event => {
// Do we trust the sender of this message? (might be different from what we originally opened, for example).
if (event.origin !== websiteHomeUrlNoSlash) {
return;
}
const { data } = event;
console.log(data); //<--- THIS WHERE I'm SEEING DUPLICATES
};
//Invoke the function
openSignInWindow(url, name);
在弹出窗口中,用户登录到他们的社交帐户,然后被重定向到我的应用程序上的一个页面,下面的代码是 运行。该代码将一条消息发回到开头 window,然后关闭弹出窗口:
// Get the message data
const messageObj = {
pluginReason: pluginReasonVar,
displayName: displayNameVar,
provider: providerVar,
};
if (window.opener) {
// send them to the opening window
window.opener.postMessage(messageObj, websiteHomeUrlNoSlash);
// close the popup
if (closePopup) {
window.close();
}
}
一切几乎都按预期工作。用户可以登录他们的社交帐户,所有重定向和弹出窗口的打开和关闭都可以正常工作。
问题:
如果用户在不刷新页面的情况下多次执行 Social Connect 过程,则打印到控制台的消息数据会越来越重复 运行。
例如:
- 1号运行打印一次
console.log(data)
。到目前为止,这按预期工作。 - 2号运行
console.log(data)
打印两次。它应该只打印一次。 - 3号运行
console.log(data)
打印三遍。它应该只打印一次。
Social Connect 进程每次 运行 都应该只打印一次。但不知何故,它在每个后续 运行.
上添加了一个副本这种重复不断增加,直到用户刷新页面,从一开始倒计时。
我想在 console.log(data)
点做更多的数据操作,但是当它在每个后续 运行.
如何阻止这种情况发生?
可能是监听事件没有分离?如果是这样,我该如何解决?
您已经创建了一个匿名方法 (event) => { }
作为包装器并将其附加到 addEventListener
方法。
window.addEventListener('message', event => receiveMessage(event), false);
无法删除
window.removeEventListener('message', receiveMessage);
要修复它,请进行如下更改:
window.addEventListener('message', receiveMessage, false);
同时,如果方法receiveMessage
在每次关闭window时都丢失,最好将removeEventListener
部分移到receiveMessage
中。
const receiveMessage = (event)=> {
window.removeEventListener('message', receiveMessage);
// do something else
}