How to receive message from postMessage when using window.open - javascript

First of all I know this question has been asked already in differently ways but I've combed through all the questions on stackoverflow and tried their examples but nothing is working for me.
I can not receive a message from the popup even though when I try to check for opener it exist on the popup window. The parent window where I am receiving the message from the popup does not receive anything. It ignores receiveMessage.
Parent Window
openSignInWindow = (url: any, name: any) => {
let _url = this.baseUrl + `user/account/login/${url}`;
// remove any existing event listeners
window.removeEventListener('message', this.receiveMessage);
// window features
const strWindowFeatures = 'toolbar=no, menubar=no, width=600, height=700, top=100, left=100';
if (this.windowObjectReference === null || this.windowObjectReference.closed) {
/* if the pointer to the window object in memory does not exist
or if such pointer exists but the window was closed */
this.windowObjectReference = window.open(_url, name, strWindowFeatures);
window.focus();
} else if (this.previousUrl !== _url) {
/* if the resource to load is different,
then we load it in the already opened secondary window and then
we bring such window back on top/in front of its parent window. */
this.windowObjectReference = window.open(_url, name, strWindowFeatures);
this.windowObjectReference.focus();
} else {
/* else the window reference must exist and the window
is not closed; therefore, we can bring it back on top of any other
window with the focus() method. There would be no need to re-create
the window or to reload the referenced resource. */
this.windowObjectReference.focus();
}
// add the listener for receiving a message from the popup
addEventListener('message', event => this.receiveMessage(event), false);
// assign the previous URL
console.log('Listener Called', _url);
this.previousUrl = _url;
};
receiveMessage(event) {
this.cd.detectChanges();
alert('HELLO');
console.log('Receiver called')
// Do we trust the sender of this message? (might be
// different from what we originally opened, for example).
if (event.origin !== window.location.origin) {
return;
}
const { data } = event
// console.log(data)
// console.log(data.source === 'internal-redirect')
if (data.source === 'internal-redirect') {
sessionStorage.setItem('access_token', data['access_token']);
sessionStorage.setItem('fullname', data['fullname'])
this.authService.logged_in_user = data['fullname'];
this.username.emit(true);
const redirectUrl = '/';
window.location.pathname = redirectUrl;
}
};
Popup page
const params = window.location.search;
if (window.opener) {
// send them to the opening window
window.opener.postMessage(params);
// close the popup
window.close();
}

Related

window.postMessage to popups in Angular

What I want to do:
opening an popup and send the postMessage when the popup is ready.
Problem:
I ran into Race Condition which the popup is not ready but the message is sent. I tried to listen to the "INIT" message and in the popup send back message. But the problem is when network latency or some slow computer will not receive the initial message.
The setTimeout obviously not a good solution
Code I have problem with:
Parent Window
const windowFeatures = "height=800,width=1280,toolbar=1,menubar=1,location=1";
const printWindow = window.open("/print", "Print_Me", windowFeatures);
setTimeout(() => {printWindow.postMessage({printPageStatus: "INIT"}, window.origin)}, 1000)
window.addEventListener("message", (event) => {
if(event.origin !== window.origin) return;
if(event.data.printPageStatus === "READY") {
printWindow.postMessage({message: "from parent", window.origin);
return;
}
});
The popup window
constructor() {
window.addEventListener("message", event => {
if(event.origin !== window.origin) return;
if(event.data.printPageStatus === "INIT")
this.sendReadyConfirmation(event);
if(event.data.message === "from parent") {
this.processMessages(event.data);
}
}, false);
}
sendReadyConfirmation(e): void {
e.source.postMessage({printPageStatus: "READY"}, e.origin);
}
Thank you
What you need to do is send the message when the window has loaded successfully :
const printWindow = window.open("/print", "Print_Me", windowFeatures);
printWindow.onload = () => {
printWindow.postMessage({printPageStatus: "INIT"}, window.origin)
};

JavaScript OAuth Popup window handler code

I'm using oAuth to login or sign up using gmail account and decided to use popup window to do it. I found a snippet here which describes the process. But I can't understand how I'll be able to get the values or code if the user logged in with his email.
I can open the modal by this:
//Authorization popup window code
$.oauthpopup = function(options)
{
options.windowName = options.windowName || 'ConnectWithOAuth'; // should not include space for IE
options.windowOptions = options.windowOptions || 'location=0,status=0,width=800,height=400';
options.callback = options.callback || function(){ window.location.reload(); };
var that = this;
log(options.path);
that._oauthWindow = window.open(options.path, options.windowName, options.windowOptions);
that._oauthInterval = window.setInterval(function(){
if (that._oauthWindow.closed) {
window.clearInterval(that._oauthInterval);
options.callback();
}
}, 1000);
};
And use that as follows:
$.oauthpopup({
path: urltoopen,
callback: function()
{
log('callback');
//do callback stuff
}
});
But now, I'm wondering how to auto close the popup and pass parameters from popup window to the main window.

Service Worker onClick event - How to open url in window withing sw scope?

I have service worker which handles push notification click event:
self.addEventListener('notificationclick', function (e) {
e.notification.close();
e.waitUntil(
clients.openWindow(e.notification.data.url)
);
});
When notification comes it takes url from data and displays it in new window.
The code works, however, I want different behavior. When User clicks on the link, then it should check if there is any opened window within service worker scope. If yes, then it should focus on the window and navigate to the given url.
I have checked this answer but it is not exactly what I want.
Any idea how it can be done?
P.S. I wrote this code but it still doesn't work. The first two messages are however shown in the log.
self.addEventListener('notificationclick', function (e) {
e.notification.close();
var redirectUrl = e.notification.data.redirect_url.toString();
var scopeUrl = e.notification.data.scope_url.toString();
console.log(redirectUrl);
console.log(scopeUrl);
e.waitUntil(
clients.matchAll({type: 'window'}).then(function(clients) {
for (i = 0; i < clients.length; i++) {
console.log(clients[i].url);
if (clients[i].url.toString().indexOf(scopeUrl) !== -1) {
// Scope url is the part of main url
clients[i].navigate(givenUrl);
clients[i].focus();
break;
}
}
})
);
});
Ok, here is the piece of code which works as expected. Notice that I am passing scope_url together with redirect_url into the web notification. After that I am checking if scope_url is part of sw location. Only after that I navigate to redirect_url.
self.addEventListener('notificationclick', function (e) {
e.notification.close();
var redirectUrl = e.notification.data.redirect_url;
var scopeUrl = e.notification.data.scope_url;
e.waitUntil(
clients.matchAll({includeUncontrolled: true, type: 'window'}).then(function(clients) {
for (i = 0; i < clients.length; i++) {
if (clients[i].url.indexOf(scopeUrl) !== -1) {
// Scope url is the part of main url
clients[i].navigate(redirectUrl);
clients[i].focus();
break;
}
}
})
);
});
If I understand you correctly, most of the code you linked to works here.
First retrieve all the clients
If there are more than one, choose one of them
Navigate that to somewhere and focus
Else open a new window
Right?
event.waitUntil(
clients.matchAll({type: 'window'})
.then(clients => {
// clients is an array with all the clients
if (clients.length > 0) {
// if you have multiple clients, decide
// choose one of the clients here
const someClient = clients[..someindex..]
return someClient.navigate(navigationUrl)
.then(client => client.focus());
} else {
// if you don't have any clients
return clients.openWindow(navigationUrl);
}
})
);

Opening two instances of InAppBrowser (_system and _blank) prevents events from triggering

We’re currently developing an app with cordova and the InAppBrowser plugin. We're trying to spawn two different IAB instances at the same time. One with the _system browser and another with the _blank option.
The problem we have is that once we open the instance of _system browser, it seems we lose the reference to the previous browser. For this reason, the close event never triggers on the _blank IAB after the _system browser is closed.
This is how the actual code looks like.
// Opening iab main window
var ref = window.open(global.chat_mediador, '_blank','location=no,toolbar=yes');
var handleEvents = function(event) {
// Closing the iab window
if (event.url.match('#close')) {
ref.close();
}
// Trigger custom event
if (event.url.match('#openccard')) {
window.open('https://www.test.example.url.com?customerID=' + event.customerId, '_system', 'location=yes');
}
}
// InAppBrowser events
// This events are duplicated because loadstop works on android and
// loadstart works on ios.
ref.addEventListener('loadstart', handleEvents, false);
ref.addEventListener('loadstop', handleEvents, false);
// Removing the dialog when we close the chat
ref.addEventListener('exit', function(event) {
generali.dialog.close();
}, false);
As you can see we open the first url within the application with the _blank option. Then if in the child application a button is pressed we want to open an instance of a browser in the _system browser.
We’ve tried (without luck) to:
Have a separate reference for the _system browser.
window.open(global.url_ficha + customerId, '_system','location=no');
var cardsRef = window.open(
'https://www.test.example.url.com?customerID=' + customerId,
'_system',
'location=yes'
);
Trigger a custom event outside the reference of the _blank browser
if (event.url.match('openccard')) {
var customerId = event.url.split('openccard-')[1];
var evt = document.createEvent("Event");
evt.initEvent("openccard",true,true);
evt.customerId = customerId;
document.dispatchEvent(evt);
}
Anyone has an idea of what's happening?
It seems that you need to initialize the IAB each time you do a new window.open() if you don't do that the event listeners don't work.
If I use that code it works like a charm.
window.openIAB = function(url, target, options) {
var self = this;
var ref = window.open(url, target, options);
var handleChildEvents = function(ev) {
if (ref != undefined) {
// Closing the iab window
if (ev.url.match('#close')) {
ref.close();
ref = undefined;
}
// Opening card url with system browser
if (ev.url.match('#openccard')) {
var customerId = ev.url.split('#openccard-')[1];
self.ref2 = self.openIAB(
'https://www.test.com?customerID=' + customerId,
'_system',
'location=yes'
);
}
} else {
console.log('InAppBrowser has no reference');
}
};
ref.addEventListener('loadstart', handleChildEvents);
ref.addEventListener('loadstop', handleChildEvents);
ref.addEventListener('loaderror', function(ev) {
console.log('error while loading page');
ref.close();
ref = undefined;
});
ref.addEventListener('exit', function(ev) {
dialog.close();
});
return ref;
};

Pop Up Blocker in Chrome and IE

Below is the piece of code I am using to open a link in a new window say "abc".
If the user again clicks on the same link, it should close and reopen the link in the same window "abc".
window.openOrFocus = function(url, "abc") {
if (!window.popups) {
window.popups = {};}
if (window.popups["abc"]){
var v=window.open("", "abc");
v.close();}
window.popups["abc"] = window.open(url, "abc");
}
But Now, say I click on the link, it opens the URL in a new window named "abc".
Now I go and close the window "abc". and go back and again click on the link.
That time it shows up the pop up blocker.
I am confused as to why this pop up blocker is coming when the I go and manually close the window and try to reopen by clicking on the link.
Happens both in IE as well as Chrome
Probably because you're calling window.open with a blank URL or repeatedly in that case.
You don't need your window.open("", "abc") call; instead, just use the window reference you already have:
window.openOrFocus = function(url, windowName) {
if (!window.popups) {
window.popups = {};
}
if (window.popups[windowName]){
window.popups[windowName].close();
}
window.popups[windowName] = window.open(url, windowName);
};
I would also listen for the unload event so you can remove your reference:
window.openOrFocus = function(url, windowName) {
if (!window.popups) {
window.popups = {};
}
if (window.popups[windowName]){
window.popups[windowName].close();
}
window.popups[windowName] = window.open(url, windowName);
window.popups[windowName].onunload = function() {
delete window.popups[windowName];
};
};
Side note: This is a syntax error:
window.openOrFocus = function(url, "abc") {
// --------------------------------^
I've replaced it with windowName in the code above.

Categories

Resources