How to reload http window.opener from https popup? - javascript

I have an http window which opens a secure popup to submit a form to a third party web site. After the popup is closed, I would like to reload the opener so that it reflects the results of the form submission.
Since the opener and the popup use different protocols (http and https), I can't do it in the straightforward way (window.opener.location.reload()). Is there another way? Do I have to venture into JSONP?

Kludgy way: set timeout to check if opened popup was closed.
function checkClosed(){
if(new_win.closed){
alert('Window was closed');
}
else{
window.setTimeout(checkClosed,1000);
}
}
new_win = window.open('about:blank');
window.setTimeout(checkClosed,1000);

I know that this is a super old question, but I found a better way to do this: Cross-document messaging:
$('a#popup').on('click', function(event) {
event.preventDefault();
$this = $(this);
authenticationWindow = window.open($this.href, 'authenticationPopup');
});
window.addEventListener('message', function (evt) {
// simplified, should check for matching event.origin
if (event.data == 'OK' && event.origin == window.location.protocol+'//'+window.location.host) {
authenticationWindow.close();
}
});
While from the pop up (of course if you control it, at least the last page) you need this:
opener.postMessage('OK', window.location.protocol+'//'+window.location.host);
This will close the popup, and allows you to do other stuff as well, like update data via Ajax or reload the page.

Related

Messenger on different windows issue

I have a messenger on PHP/js, imported to all pages of the website. The messenger works through ajax, checking for new messages each 5 seconds.
Also I have desktop and sound notifications.
The problem is, if I opened multiple pages, and I'm currently on one of them, the reminder may come from another page, which is currently not active. However, inactive pages should notify only if the active page is not the same website.
Ideas?
Check for window focus:
var window_focus;
$(window).focus(function() {
window_focus = true;
}).blur(function() {
window_focus = false;
});
Check if location.host matches specified domain and window is focused:
if((location.host == "example.com")&&(window_focus == true))
{
//window is focused and on specified domain for that website.
//sounds, notifications, etc. here
}
Not completely sure if this is what you mean, but I hope it helps.

Keep Popup Open when Opening a new Page

I have the following code to introduce my Chrome Extension.
// detect if this is the first time running
var first_run = false;
if (!localStorage['ran_before']) {
first_run = true;
localStorage['ran_before'] = '1';
}
// if not, start the intro() script
if (first_run) intro();
// intro script
function intro() {
window.open("intro/index.html", '_blank');
}
But sadly, when I click the extension, it doesn't open the popup.html but just opens the intro page.. it needs to keep the popup.html open and I'm sure there is a way to do this. I want to open them both at the same time.
What is the best way to do this?
the method you are using is valid and should work, but you should probably
just use the onInstalled event for consistency:
chrome.runtime.onInstalled.addListener(function(info){
if(info.reason == "install"){
console.log("Installed!");
}else if(info.reason == "update"){
console.log("Updated!");
}
});
It doesn't require new permissions, and will keep your install code clearly separated from the rest of your code.
While Marc Guiselin's answer is excellent, it may be useful to know how to open a tab without closing a popup.
You could open the tab in the background, that way it won't close your popup.
chrome.tabs.create({
url: chrome.runtime.getURL("intro/index.html"),
active: false
});
In general, you should avoid using window.open in extensions and use chrome.tabs and chrome.windows API instead.

How do I get around window.opener cross-domain security

I just found out that window.opener is not available in a window opened via window.open if the new URL is cross-domain, in IE. How do I detect window opener in IE
This will happen if the window starts in my domain, leaves it, and then comes back to my domain. I am attempting to have a social signup ( facebook, google, etc ) in the popup. When it completes it should close the new window and redirect the opener.
I know that Soundcloud is pulling this off, but I have no idea how. I see the URL change from theirs to Facebook, and then close.
After redirecting back to my site from 3rd party I run this:
var data = {
type : 'complete',
destination : '<?= $destination; ?>'
};
if ( window.opener ) {
window.opener.postMessage( JSON.stringify( data ), '*' );
window.close();
}
else {
alert( "Unable to find window" );
}
It alerts out in IE, even though the window was originally my domain, which then redirected to FB, then redirected back to me. I thought may since I open my site and redirect immediately from PHP that may be an issue. However even when I opened my site, did window.location.href = 'facebookssite.com' it still complained when returning.
NOTE
Social signups do not work for google, FB, etc within an iframe. I believe they disallow them for security reasons.
Do it the other way around. Track the state of the child popup window from the main (opener) window, and you could easily know when the child window has been navigated back to you domain, so you could "talk" to it again. But don't close the child window by itself. Let the opener window obtain the result from the child window and then close it.
For example, main.html:
<!DOCTYPE html>
<head>
<title>main</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<script>
window.addEventListener("message", function(ev) {
if (ev.data.message === "deliverResult") {
alert("result: " + ev.data.result);
ev.source.close();
}
});
function Go() {
var child = window.open("child.html", "_blank", "height=200,width=200");
var leftDomain = false;
var interval = setInterval(function() {
try {
if (child.document.domain === document.domain) {
if (leftDomain && child.document.readyState === "complete") {
// we're here when the child window returned to our domain
clearInterval(interval);
alert("returned: " + child.document.URL);
child.postMessage({ message: "requestResult" }, "*");
}
}
else {
// this code should never be reached,
// as the x-site security check throws
// but just in case
leftDomain = true;
}
}
catch(e) {
// we're here when the child window has been navigated away or closed
if (child.closed) {
clearInterval(interval);
alert("closed");
return;
}
// navigated to another domain
leftDomain = true;
}
}, 500);
}
</script>
</head>
<body>
<button onclick="Go()">Go</button>
</body>
child.html:
<!DOCTYPE html>
<head>
<title>child</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<script>
window.addEventListener("message", function(ev) {
if (ev.data.message === "requestResult") {
// ev.source is the opener
ev.source.postMessage({ message: "deliverResult", result: true }, "*");
}
});
</script>
</head>
<body>
Go to example.com
Then click the browser Back button when ready.
</body>
Tested with IE10.
Due to security reason, window.opener is removed when redirecting to a different domain. The browser does not bother to restore the window.opener when you're back. In your case, you could try:
1) Do your authentication inside an iframe if possible instead of using redirect.
2) In your case, I see that you need to post the data back to the parent window. You could try this instead:
In your opened window, just store your data and close normally.
var data = {
type : 'complete',
destination : '<?= $destination; ?>'
};
window.hasData = true;
window.data = data;
window.close();
Your parent window has access to your opened window and can handle its close event:
openedWindow.beforeunload = function (){
//here you could access this.data or openedWindow.data because you're on the same domain
if (this.hasData){
}
//Reason we have this check is because the beforeunload event fires whenever the user leaves your page for any reason including close, submit, clicking a link, ...
}
3) A workaround: Use a timer in your parent page to check for the closed property of the openedWindow
setInterval(function(){
if (openedWindow.closed){
}
},1000);
4) Another solution using localStorage as you're on the same domain. You parent page can listen to the event
window.addEventListener("storage", function(event){
}, true);
Your openedWindow code:
var data = {
type : 'complete',
destination : '<?= $destination; ?>'
};
if (localStorage){
localStorage.setItem(JSON.stringify(data));
}
window.close();
From your iframe, webpage, on yoursite.com ... open a new window on yoursite.com
The window redirects itself to Google, Twitter, whatever
Once done, the OAuth redirect returns the window to a page on yoursite.com
The new window, because it has the same origin as the page that opened it, can communicate via window.open
Use localStorage or IndexedDB to communicate between windows that are showing documents from the same domain but which don't have a reference to each other.
Simply have a high-speed timer checking for the data, saving another piece of data to acknowledge receipt and the other window can find it and close.
In short - you use localStorage to pass commands and can even have a library to do this and delete the commands once they are executed, and post the return values.
You can use use window.postMessage(), which is provided for this exact scenario.
Explanation: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
In my company we've different domains and there's the case where the intranet's site must get the our public website (to finally get rid of the maintenance of duplicated data).
Inspired in Ben Vinegar i've come to this solution simple solution avoiding the :
Call to domain webpage (in my case with the same name as the external one)
local 'getInfo.php'
<?php
$idSp = (isset($_GET['idSp'])?$_GET['idSp']:null);
echo file_get_contents('http://192.168.1.10/folder/getInfo.php?idSp='.$idSp);
?>
External 'getInfo.php' return
<?php
echo '<script>window.opener.manageDisplay('.$getRes.','.$isOK.');</script>';
if($auto_close){ echo "<script>window.close();</script>"; }
?>

Listen to Child window close event in Oauth Like Situation [ jQuery| Javascript ]

I am using oAuth 1.0 to access 3rd party data.
For this I am taking following steps :-
User clicks on "sync with 3rd party" button. ( It is necessary for user to click because this usually doesn't invoke popup blocker.)
When user click on this button following code is executed :
$('#sync_with_thirdparty').click(function(){
var child = window.open('/oauth');
$(child).unload(function() {
if (this.location != "about:blank") {
alert("Child window closed");
}
});
});
Now in the new window PHP get the authentication URL from 3rd party then it redirects the user to the same URL. As soon as user redirects to 3rd party above code says that "child window closed.".
Then user makes himself login on third party site (if necessary) and gives access to our app. As soon as he clicks on allow button third party redirects the user to a new page in our website. On this page I am calling window.close() method which is working perfectly fine.
But upon window.close() in child window, parent window is not able to know that child is closed.
How I can solve this problem?
Note : This 3rd doesn't like Iframe and refreshes itself to open in top window. I don't have any control over 3rd party's content. Our webpage is in HTML5 format.
The child window can communicate with the parent window via the window.opener() function. You could do something like this:
Child window
window.opener.messageFromChildWindow('closed');
Parent window
function messageFromChildWindow(msg) {
if(msg === 'closed') {
alert('child window closed');
}
}
You can not access the content or events activity of a child window, as there are permission issues with it in Javascript.
Well, if things are on same domain, you should try once doing the document.domain same in both the window forcely.
like:
var hdomain="yourdomain.com";
if (document.domain != hdomain){
if ((document.domain.indexOf(hdomain)) != -1){
document.domain = hdomain
}
}
put this in both the pages the parent and the child.
Good luck.

javascript's unload and beforeunload alternative

I need to monitor when the user moves away from a page (to a different site not the same site) or closes the window/tab. I can achieve that with $(window).bind('unload', function() {}); but onload is a catch-all event: it also catches page refresh and navigating to a different page on the same website. How can I detect those two events (page refresh and navigating to another page in the same website) using javascript/jQuery please?
I think that isn't possible, I don't know such an event.
A possible solution is to compare the current url with the destination url but that's not possible because of security and privacy reasons see:
How can i get the destination url in javascript onbeforeunload event?
On each page,
var leaving = true;
$(function() {
$('a[rel!=ext]').click(function () { leaving = false; });
$('form').submit(function () { leaving = false; });
});
$(function() { window.onbeforeunload = unloadPage; });
function unloadPage() {
if(leaving) {
// Put your logic here
}
}
Then just make sure that all links to external sites have a rel="ext" attribute.

Categories