Hello all! Hope you are coding well!
While working on one of my projects, I came across a scenario where I wanted to communicate with a cross-domain site, that opened as a popup from my main site. Also, based on the ‘Title’ of that popup page, I wanted to perform another operation.
Every coder might have come across such a situation, where he wanted to access content from a different domain-site while working on his main-site.
We usually open popup windows on the client-site as:
var popupObj = window.open(<url>, '', "width=800, height=500");
Here, <url> is the site link to open in a popup window.
This way, we get an object of the newly opened popup as ‘popupObj’.
I believed, once we get this object, we can access all of its properties. I tried to access its Title Property:
var popupTitle =popup.document.title ;
But I was wrong! The page throws an error:
Blocked a frame with origin http://localhost:55032 from accessing a cross-origin frame.
(Here, http://localhost:55032 is my main site)
Reason? Cross-domain security!
Normally, scripts on different pages are allowed to access each other if and only if the pages they originate from share the same protocol, port number, and host (also known as the “same-origin policy“).
You cannot access a popup (or another window) with different origins using JavaScript; it would be a huge security flaw. In such a scenario, it blocks the script’s execution.
Origin is considered different if any one of the following parts of the address isn’t maintained – protocol (HTTP/https), hostname or port number.
<protocol>://<hostname>:<port>/path/to/page.html
After trying multiple options, I came across a solution which is easy to use:
(Source: window.postMessage)
The condition is, we need to own both the pages i.e. main page and the newly opened popup window page. This is because, one needs to add event listener script to the newly opened popup window too.
Here is a sample script
At Main Page script section:
var popup = window.open(url, ' ', "width=800, height=500"); var popupTick = setInterval(function () { popup.postMessage("requestResult", "<NewPopUpWindow Link>"); }, 500);
At new Popup window page script section :
window.addEventListener('message', function (event) { //IMPORTANT: Check the origin of the data! if (event.origin.indexOf('http://localhost:55032')>-1 && document.title.indexOf('Payment')>-1) { //Implement execution logic here //The data sent with postMessage is stored in event.data console.log(event.data); } else { // The data hasn't been sent from your site! Be careful! Do not use it. return; } });
Here, I am checking if the opened popup window’s Title contains the word ‘Payment’. As a security check, by using event .origin, I am also checking is if the event is coming from the desired site.
event.origin gives us URL of a site from where a window.postMessage event is triggered.
Oh wait! Here, I am only executing an action at a newly opened popup window site.
What if, after performing the required action on the newly opened site, I want to perform some action on the main site?
No worries. Here is the solution…
How?
- At new Popup window page script section :
window.addEventListener('message', function (event) { if (event.origin.indexOf('http://localhost:55032')>-1 && document.title.indexOf('Payment')>-1) { event.source.postMessage('deliverResult', '*') //Posting message back to main site console.log(event.data); } else { return; } });
On ‘Title’ condition match, I am posting a message back to the parent site.
as : event.source.postMessage('deliverResult', '*')
- Add an event listener to our main site page script as :
window.addEventListener("message", function (ev) { if (ev.data === "deliverResult") { var time = new Date(); startPayment(); //performing my operation at main site console.log("Payment started at : " + time); } });
Here, we are checking ev.data === “deliverResult”, which means, the condition is satisfied at another newly opened popup window. and post message event is triggered form the same site. You can now perform the desired operation on the main site.
This concludes that, though we are working on cross-domain sites using MVC applications, we can communicate between them!
Happy coding!!
“Vishal Himane is a consultant at Systems Plus. The content of this blog is personal & for information purposes only, and is subject to change. Reader discretion is advised”