在 Firefox 和 Safari 中的 iframe 和页面之间共享本地存储 - Vanilla JavaScript

问题描述 投票:0回答:1

您能帮忙解决以下问题吗? 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>
javascript firefox iframe local-storage postmessage
1个回答
0
投票

我自己的问题有了答案:

在 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
© www.soinside.com 2019 - 2024. All rights reserved.