javascriptcross-domainpostmessage

JS - Passing SessionStorage variable from Parent page to iFrame Popup? - cross domain


This is in JavaScript. I am looking to pass a variable that is saved in SessionStorage on the Parent page (domain https://parent.com/) to an iframe Popup that loads after 10 seconds (domain https://iframe.com/).

I am sure that I will have to use postMessage but I can't seem to figure it out.

Any help would be much appreciated. Thanks!


Solution

  • You need to use window.postMessage() in the parent window along with window.addEventListener() inside the iframe to receive the message. Make sure to send the message when your iframe is loaded; otherwise, your message will be lost.

    Additionally, pay attention to the origin of the message when you are listening for it, to ignore messages that you don't want or shouldn't affect your app.

    You didn't mention whether you are using a framework or just vanilla JavaScript, so the implementation might vary depending on your environment.

    If it can be useful i use a custom hook in one of my react projects to do so.

    function useMsgReceiver(options: MessageHandlerOptions) {
        const { origin, source, onMessage } = options;
    
        useEffect(() => {
            const handleMessage = async (event: MessageEvent) => {
                if (event.origin !== origin) return;
                try {
                    const message = event.data;
                    if (message.source !== source) {
                        console.error("Source not expected");
                        return;
                    }
                    await onMessage(message.type, message.payload);
                } catch (error) {
                    console.error("Error while parsing the messagge: ", error);
                }
            };
    
            window.addEventListener('message', handleMessage);
    
            return () => {
                window.removeEventListener('message', handleMessage);
            };
        }, [onMessage, origin, source]);
    

    And here i use the hook inside the components:

    useMsgReceiver({
        origin: PARENT_ORIGIN,
        source: CUSTOM_SRC,
        onMessage: handleMessage
    });
    

    As you can see i use a type defition on the message exchanged composed by source, payload and type to do additional checks but you can limit yourself to use message.origin and message.data if you have not other needs.