您能帮忙解决以下问题吗? domaina.com/parent.html 包含一个带有 src=domainb.com/iframe.html 的 iframe。当我们单击domaina.com/parent.html 上的按钮时,我们使用postMessage 和localStorage 将URL 传递到iframe。我们将有多个具有不同 URL 的按钮。然后,我们被重定向到domainb.com/iframe.html。然后,我们从 localStorage 检索 URL,我们将被重定向到该 URL。以下代码在 Chrome 中运行良好,但在 Firefox 和 Safari 中运行不佳;我可以将 iframe 中的 URL 保存到 localStorage,但是一旦我重定向到 iframe 页面,该 URL 就不在 domainb.com 上的 localStorage 中。添加查询参数不是一个选项。
parent.html:
<!DOCTYPE html>
<html>
<head>
<title>Parent Window</title>
</head>
<body>
<iframe id="iframe-id" src="https://domainb.com/iframe.html" width="500" height="200">
</iframe>
<div class="button" role="button" tabindex="0" style="cursor:pointer">Click Me</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
document.querySelector('.button').addEventListener('click', (event) => {
setTimeout(() => {
const iframeDomain = 'https://domainb.com'; // Set the correct iframe domain here
const data = doSomethingToGetData();
const iframe = document.getElementById('iframe-id');
// Send data to the iframe to save
iframe.contentWindow.postMessage({
action: 'save',
key: 'myKey',
value: data
}, iframeDomain);
// Request data from the iframe
iframe.contentWindow.postMessage({
action: 'get',
key: 'myKey'
}, iframeDomain);
window.addEventListener("message", messageHandler, false);
function messageHandler(event) {
console.log(event)
if (event.origin !== iframeDomain) {
return; // Reject messages from unknown origins
}
const { action, key, value } = event.data;
if (action == 'returnData') {
useData(key, value);
}
}
// Function to simulate getting data
function doSomethingToGetData() {
return "https://redirect.com";
}
// Function to handle the returned data from the iframe
function useData(key, value) {
console.log('Received Data Key:', key);
console.log('Received Data Value:', value);
}
location.href = 'https://domainb.com/iframe.html';
}, 2000);
});
});
</script>
</body>
</html>
iframe.html
<!DOCTYPE html>
<html>
<head>
<title>Iframe Window</title>
</head>
<body>
<script>
document.addEventListener('DOMContentLoaded', () => {
const domains = [
"https://domaina.com", // Add parent domain to the whitelist
"https://domainb.com"
];
window.addEventListener("message", messageHandler, false);
// Check if the page is the top-level window (not inside an iframe)
if (window === window.top) {
window.location.href = getDataFromLocalStorage("myKey");
}
function messageHandler(event) {
if (!domains.includes(event.origin))
return;
const { action, key } = event.data;
if (action === 'save') {
const value = event.data.value;
saveDataToLocalStorage(key, value);
} else if (action === 'get') {
const value = getDataFromLocalStorage(key);
event.source.postMessage({
action: 'returnData',
key,
value
}, event.origin);
}
}
// Function to save data to localStorage
function saveDataToLocalStorage(key, value) {
window.localStorage.setItem(key, JSON.stringify(value));
}
// Function to get data from localStorage
function getDataFromLocalStorage(key) {
const value = window.localStorage.getItem(key);
return value ? JSON.parse(value) : null;
}
});
</script>
</body>
</html>
我自己的问题有了答案:
在 iframe.html 上添加了一条带有“dataSaved”操作的 postMessage,以向父级响应数据已保存:
//existing code
if (action === 'save') {
const value = event.data.value;
saveDataToLocalStorage(key, value);
// Respond back to the parent that data has been saved
event.source.postMessage({
action: 'dataSaved',
key,
value
}, event.origin);
}
//existing code
在parent.html上添加了一个监听器,用于在收到数据后导航到新的URL:
//existing code
if (action == 'returnData') {
useData(key, value);
}
else if (action === 'dataSaved') {
// After receiving data, navigate to the new URL
location.href = value;
}
//existing code