Cross-origin communication in between iframe and it’s parent website

February 14, 2018 0 Comments

Cross-origin communication in between iframe and it’s parent website

 

 

Yes, it’s not any hack or something, but with simple functions you can communicate in between iframe and it’s parent website. First of all, let’s know about the iframe. ‘iframe’ is very popular html tag which enables you to keep another webpage inside a webpage. It is important for so many aspects, like the chat application we were building for Trilyo, a bot-messaging app, most of the things are handled inside multiple iframes. That was a complex application, but let’s not get into that. Instead I will demonstrate a simple application, where the parent website and the website inside the iframe can talk to each-other without any problem. And guess what, for this communication, it’s not required to both websites have to be under same domain. Cross-origin communication is also possible.

So, first of all, we will create a page where I am placing a textarea and an iframe. My aim is to transfer message from the textarea to the iframe.

<!-- this is source. You can input something in textarea --> <textarea id="source" placeholder="Write something here" cols=30 rows=5 ></textarea> <!-- This is destination iframe --> <iframe id="destination" src="http://some-othersite.com/some-page.html"></iframe>

For that, first of all we need to get the data inside textarea by javascript. So if we use jquery, it’s pretty simple.

$(document).on('keyup','#source',function(){ var data = $(this).val(); })

So, when someone is typing on textarea, we are receiving the value inside the ‘data’ variable. Now we need to transmit it to the iframe. For that first of all we need to address the iframe. As the iframe got an ID named ‘source’. So, with javascript, it’s simple to get the element.

var destination = document.getElementById('destination');

But as we are targetting the content inside the iframe, we need to address the contentwindow inside the iframe. So the code will be like below –

var destination = document.getElementById('destination').contentWindow;

The contentWindow property returns the Window object generated by an iframe element (through the window object, you can access the document object and then any one of the document’s elements).

Now as we got the destination, we will use postMessage method to communicate.

The structure of the method is below –

targetWindow.postMessage(message, targetOrigin, [transfer]);

Where targetWindow is the iframe contentwindow element we have declared in  ‘destination’ variable. message is the value of textarea stored inside data variable.

The new part is targetorigin. So we can declare a url like www.somespecialurl.com. So if iframe loads specifically any page from that URL will be able to receive the message. If you would like to transmit message to any website inside the iframe, you need to declare it by “*” instead of a generic URL.

Another new part is transfer, it is used in case you send multiple transfarable objects from parent to content inside iframe. As it’s not used often, I am not discussing it here and also this parameter is optional for postMessage method.

So what we get is this –

destination.postMessage(data,"*");

So, it will transfer the data variable to the iframe which is defined as ‘destination’.

So, the complete code for sending below – 

$(document).on('keyup','#source',function(){ var data = $(this).val(); var destination = document.getElementById("destination").contentWindow; destination.postMessage(data,'*'); })

Now at the receiving end, we have to listen the incoming message and do action. For that we need to write following codes inside the website loaded into iframe –

Suppose the iframe has following html inside it –

<h1 id="output">I am the website inside iframe</h1>

Now we have to listen the incoming message and display it inside the h1 tag which has an ID named “output”.

For that we need to add following code inside the script tag.

The receiving

<script type="text/javascript"> var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent"; var eventer = window[eventMethod]; var messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message"; eventer(messageEvent, function (e) { //data you receive from parent is stored inside e.data $('#output').text(e.data); }); </script>

Now you are done. You can see, whatever you type inside the textarea, will be displayed inside the iframe’s output ID.

Now the process is almost same for transmitting message from iframe to parent window. For that, you need to define the targetwindow differently.

In case of transmitting message from iframe to parent window, you need to define it like below –

parent.postMessage(message you want to send,'*');

If you would like to transmit message to any specific parent url, you can change the second parameter ‘*’ to ‘http://www.your-url.com’;

On both end, if you want to be very specific about domain, you can differentiate by catching event.origin

Like the code below –

 eventer(messageEvent, function (e) { if(e.origin == "http://iframe1-domain.com"){ //do this action } else if(e.origin == "http://iframe2-domain.com"){ // do second action } else{ // do another action } }); 

The sending-receiving process is updated in pen –

https://codepen.io/Showvhick2/pen/ddzpKW

Also, if you would like to study more about postMessage method read mozilla web docs for more- https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage 

For any confusion, reach out to me. Comment below or send me mail to showvhick@redelegant.com

Also, if you have any project which requires this connectivity, reach out to us, we might be able to help you out.

Also published on Medium.


Tag cloud