[SalesForce] window.postMessage does not work in lightning console app. Any workaround

We have an flexipage/app which have 5 lightning components on it. Out of these 5, 3 are lightning component and 2 are visual force pages embedded inside lightning component.

I went through https://developer.salesforce.com/blogs/developer-relations/2017/01/lightning-visualforce-communication.html and I am posting events and catching the events on the cards. This works perfectly when a single tab is opened on the lightning console app.

But when multiple tabs are opened with different data, the first tab reloads and posts the event window.postMessage(response, '*');. Now as it is posting events to the window the second tab also listens to the message and reloads the components as javascript code remains same.

Has anyone faced this issue till now?

Still did not find a solution for this. The issue is we can have multiple tabs and subtabs opened, and each tabs and subtabs are having same header components which posts the message, now as far as I know, lightning console does not generate different javascript from the component for each tab and subtab. it uses the same javascript every where, thus the given solution fails .

If there is a way to postMessage to a particular tab or subtab then it would be helpful.

Best Answer

This is an expected behaviour since postMessage with targetOrigin '*' sends the message with no target preference and your tabs are in the same lightning container.

The window.postMessage() method safely enables cross-origin communication between Window objects; e.g., between a page and a pop-up that it spawned, or between a page and an iframe embedded within it.

What you can do is you can send the id of the data you are handling for each tab as part of the message and use it to decide if you want to do event handling or not.

There is an explanation about one-to-many communication here in One-to-One vs One-to-Many Messaging Scheme.

var message = {
   objectId: "your-object-id",
   payload: payload
 };
 window.postMessage(message, '*');

In receiving end:

if (event.data.objectId === "your-object-id") {
    // Handle the message
    console.log(event.data.payload);
}

Also it is a good idea to specify targetOrigin as using '*' is not safe depending on the data you are sending.

Documentation on postMessage

Related Topic