我有一个iframe,它正在与其父窗口进行通信,以通过postMessage方法设置和获取一些必要的cookie 。
首先,iframe应用程序中的一个函数从父窗口请求CookieA。
function requestCommunication(topic, customerId) {
function cookieAvailable() {
return new Promise((resolve) => resolve(getCookieData('cookieName'));
});
}
console.log(cookieAvailable());
if(!!cookieAvailable()) {
//doStuff
}
}
cookieAvailable()
触发从iframe发送到parent.window的消息。反过来,窗口返回cookie及其数据作为字符串。通过使用以下操作完成此操作:
async function getCookieData(cookieName) {
const {data} = await new Promise(resolve => {
window.onmessage = (event) => {
resolve(event);
}
});
var cookieContent = JSON.parse(data);
var cookieContentData = JSON.parse(cookieContent.data);
return cookieContentData; //this returns the cookie data (in almost all cases)
}
我没有如何正确使用诺言将其移交给我的初始触发功能。我将不胜感激。
您的代码中存在明显的问题和反模式。cookieAvailable
将返回一个Promise,因此您的支票if(!!cookieAvailable()) {
永远是真实的。您将要等待该Promise解决,然后再检查是否确实存在cookie。
但是实际上,您的cookieAvailable
函数将thisChatClient.cookie.getCookieData
不返回任何内容的Promise包装器:如果确实返回了Promise,则直接将其返回,无需将其包装在Promise中。
而且,如果返回同步结果,则只能通过将其包装在Promise中来放松
async function requestCommunication(topic, customerId) {
function cookieAvailable() {
// this is already a Promise
return thisChatClient.cookie.getCookieData('sess_au');
}
const isCookieAvailable = await cookieAvailable();
if (!!isCookieAvailable) {
}
}
requestCommunication().catch(console.error);
现在,所有这些都无助于正确回答您的问题:两个代码块之间的链接根本不清楚。
没有什么叫任何功能。
您getCookieData
将等待一个MessageEvent,而不会让任何人知道它正在等待它。
我不确定您是如何计划让iframe知道应该将包含此信息的消息发送到窗口的,但是您必须考虑这一点。
但是在去那之前,我应该注意:尽管很诱人,但是将事件包装在Promises中通常不是一个好主意。
事件和承诺是不同的事物,后者应仅解决一次,而前者可能会多次触发,并且来自不同的来源。
IMM,只有在您确定事件只会触发一次时才这样做。使用MessageEvent,您远不了解它。
您的用户很可能在其浏览器上具有一个扩展名,该扩展名将使用postMessage作为通信方式。如果将此扩展名添加到所有iframe上,则您的代码已损坏。
相反,您应该检查MessageChannel API,它将为您提供通信方式,可以确保您将是唯一使用的通信方式。
我认为此答案不是解释此API如何工作的正确位置,但请看一下概述了基本知识的概述。
由于您将确保控制两端,因此您可以从那里建立一个基于Promise的系统。
在您的主页上,您将准备MessageChannel对象,并在侦听响应时将其发送到iframe。收到答复后,您就可以解决您的Promise。
在iframe中,您将在窗口上添加一个侦听器以捕获MessageChannelPort。发生这种情况时,您将向您的服务询问cookie,然后通过MessageChannel的端口将其发送回去。
即使在交换过程中在主窗口上出现一条消息,您也可以确保它不会成为您正在等待的消息。
// Sets up a new MessageChannel
// so we can return a Promise
function getCookieData() {
return new Promise((resolve) => {
const channel = new MessageChannel();
// this will fire when iframe will answer
channel.port1.onmessage = e => resolve(e.data);
// let iframe know we're expecting an answer
// send it its own port
frame.contentWindow.postMessage('getCookie', '*', [channel.port2]);
});
}
frame.onload = async e => {
const frameHasCookie = await getCookieData();
console.log(frameHasCookie);
};
frame.src = generateFrameSRC();
function generateFrameSRC() {
// The content of your iframe
const cont = `
<html>
<head>
<script>
const originClean = "null";
onmessage = async e => {
// only if it's the origin we expected
// and if it does send a MessagePort
// and the message is "getCookie"
if(e.origin === originClean && e.ports && e.data === "getCookie") {
const data = await asyncData();
// respond to main window
e.ports[0].postMessage(data);
}
};
function asyncData() {
return new Promise(resolve =>
setTimeout(() => resolve("the data"), 1000)
);
}
<\/script>
</head>
<body>
hello
</body>
</html>`;
return 'data:text/html,' + encodeURIComponent(cont)
}
<iframe id="frame"></iframe>
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句