Currently I have an application where a user hits a clicks on a URL and goes to my form. The user then enters his information into the form field, which is then sent through jquery ajax to a PHP script which enters it into the database. Upon success callback, it would alert the user that they had been registered and closes the current browser tab. (Let's just say I need the closing the browser tab behaviour to persist).
$.ajax({
type: "POST",
url: 'goToPHP',
data: data,
success: function(data){
alert('You Have Been Registered Successfully');
open(location, '_self').close();
},
error: function(data){
}
});
I understand that most modern browsers (Chrome included) are limiting the ability for javascript to only close tabs/windows it created for security reasons. Temporarily I had used open(location, '_self').close(); to get around the issue, but alas, it seems chrome's most recent update prevents you from doing this as well (Prompts you with a warning: 'Scripts may close only the windows that were opened by it'.)
Is there a way around this? I'm not talking about something along the lines of:
open(location, '_self').close();
But something that will work all the time on Chrome (e.g. changing a Chrome setting to allow scripts to close tabs/windows (similar to how this could be done through about:config in Firefox) or a way of restructuring how the user hits the form, so that the window object is available in javascript so i can call windowObject.close(); ) .
Thanks in Advance!
A browsing context is script-closable if it is an auxiliary browsing context that was created by a script (as opposed to by an action of the user), or if it is a top-level browsing context whose session history contains only one Document.
http://www.w3.org/html/wg/drafts/html/master/browsers.html#dom-window-close
In effect this means that, in common usage, you can only close windows/tabs that you have created in JavaScript. However, it is also possible to close a window or tab (but not a frame or other nested browsing context) as long as that window or tab has no history. Usually, this is a highly unreliable feature to make use of as you generally cannot realistically expect your user to have opened no documents in their browsing context before opening the one that you are trying to close; however, there are certain cases where you can safely assume that the page is in a context with no history, but generally these cases would fall under the 'opened by script' categorization as well.
Additionally, if you use a link to '#' for JavaScript purposes or any other sort of bookmark linking within your page, that will populate the session history and render the context unclosable unless you use JavaScript to prevent the hyperlink event from being executed. For purposes of JavaScript, it is probably better practice to just use javascript:void(0) if this is an issue.
In your case, the only way you can guarantee that you can close the tab/window is if you can guarantee that your form is being opened in a browsing context with no history or if you can open the form page via JavaScript. Whether or not those limitations are reasonable to work around depends on the specific structure/implementation of your website.
You can only close windows/tabs that you create yourself. That is, you
cannot programmatically close a window/tab that the user creates.
For example, if you create a window with window.open() you can close
it with window.close().
To make your code work, you should open up a window using JavaScript and then you'll will be able to close it by code.
You can use something like the below example code.
<script>
function openwindow() {
var pop = window.open("localhost","Ratting","width=550,height=170,0,status=0,")
var close = function() {
pop.close();
};
setTimeout(close, 2000);
}
</script>
<body>
<a href="javascript:void(0);" name="Window_Name" title="title_here" onClick="openwindow()" >Click here to open the child window</a>
</body>
you can use this concept on your ajax URL and ajax success stage.
$.ajax({
type: "POST",
url: function(){
var pop = window.open("localhost","Ratting","width=550,height=170,0,status=0,")
},
data: data,
success: function (resp) {
var close = function() {
pop.close();
};
setTimeout(close, 3000); // close after 3 seconds
},
error: //error code
}
});
HTML
<a class="closeButton">Close</a>
JavaScript
$('.closeButton').click(function () {
close();
});
You dont must use window.closed() or reopen tab and closed.
Just use this code.
For me its working.
I used to use the window.open(...).close() trick (which no longer works in Chrome or FireFox). In my case, there is a quit button in the (Java) application that, rather than trying to close the browser tab, cleans up, redirects back to the starting page and terminates. The user can then decide to:
manually close the tab
leave it open, or
re-enter the application
I realized that my real goal is not to close the browser tab, but to inform the user in an obvious way that the session is over.
Related
The problem
I've had this issue for months now, but the concept is pretty straightforward: I want to block some Malicious Site™ from programmatically opening tabs or popup windows.
With the chrome.tabs API, I can listen with onCreated when a new tab is created, and I can easily check who (i.e. which tab) opened that particular tab accessing the openerTabId property of the Tab object passed to the callback function.
Now, I would like to do the exact same thing when a new window is created: I would like to know which tab opened the window (if any, because it could have been opened by the user too), check its URL to see if it is the Malicious Site™, and act accordingly (i.e. block the popup). I tried doing it in the exact same way: request the array of tabs in the new window and check their openerTabId property, but unfortunately such property is not defined! I searched the documentation and Googled for hours, but sadly it looks like there's no simple way to check who opened a window.
A very clumsy solution
Stated the above, the only way I was able to do something even remotely close to what I really want, is the following:
Every time a new window is created, its ID is added to an array called windowWatchlist.
Every time a tab is updated (NB: updated, not created), a script is injected inside it to check its document.referrer, which should contain the URL of the site which opened the tab: if the referrer URL contains the address of the Malicious Site™ I want to block popups from, the window is then closed and removed from the windowWatchlist.
Every time a window is closed, if its ID is in the windowWatchlist, it gets removed from it.
Here's the code (which runs in my background.js script):
// Called on chrome.windows.onCreated
function watchPopupWindow(window) {
windowWatchlist.push(window.id);
console.log('Added window #' + window.id + ' to watchlist.');
}
// Called on chrome.windows.onRemoved
function unwatchPopupWindow(windowID) {
var index = windowWatchlist.indexOf(windowID);
// If the windowID is in the watchlist:
if (index != -1) {
// Remove it:
windowWatchlist.splice(index, 1);
console.log('Removed window #' + windowID + ' from watchlist.');
}
}
// Called on chrome.tabs.onUpdated
function blockPopupWindow(tabID, info, tab) {
// If this tab is in a window which is in the watchlist:
if (windowWatchlist.indexOf(tab.windowId) != -1 && info.url && info.url != 'about:blank') {
// Check the referrer of this tab:
chrome.tabs.executeScript(tabID, {code: 'document.referrer;'}, function(ref) {
// If the referrer is the malicious site to block:
if (ref && ref[0] && ref[0].indexOf("http://MALICIOUS-SITE.XXX") != -1) {
// Close the popup window:
chrome.windows.remove(tab.windowId, function() {
console.log('Blocked popup window #' + tab.windowId + '.');
if (chrome.runtime.lastError)
console.error(chrome.runtime.lastError.message);
});;
}
});
}
}
var windowWatchlist = [];
chrome.windows.onCreated.addListener(watchPopupWindow, {windowTypes: ['popup']});
chrome.windows.onRemoved.addListener(unwatchPopupWindow, {windowTypes: ['popup']});
chrome.tabs.onUpdated.addListener(blockPopupWindow);
Now, you may be wondering: why do you need all this mess only to check a referrer? Couldn't you just check the tabs contained in the window when the window is opened and check their referrer directly inside the callback of chrome.window.onCreated? That's a clever question, and the answer is simple: the problem is that I cannot check the referrer of the tabs right when they are created, because they almost always need some time to load, and the referrer isn't loaded until the page starts loading inside the tab. Therefore, I need to check when a tab is updated, see if its window is in my watchlist, and then check its referrer. This is why chrome.tabs.onUpdated is needed, since it fires its listeners whenever a tab changes state (e.g. tab.status changes from "loading" to "complete").
Why this solution doesn't work
The reason why I call this solution "clumsy" and the reason why it doesn't really work should be already clear to anyone with some experience of JavaScript and web developing: document.referrer isn't reliable at all, and is very often undefined or (in case of multiple redirects) not the right one. This makes my script fail about 90% of the times, because it is unable to determine whether the popup window was opened by the Malicious Site™ or not.
Moreover, the Malicious Site™ often opens popups with URL about:blank or no URL at all, and only when they are loaded, injects data into them, making them basically impossible to detect, even with chrome.tabs.onUpdated which doesn't fire any listener in this situation.
I could decide to block any popup with URL about:blank or undefined, and this is what I'm doing right now indeed, but is a pretty bad compromise, since that I end up closing popups opened by any site which uses this method, and not only the Malicious Site™ I want to block.
In conclusion
My question is simple, but I don't know about its solution: does anyone know any other more reliable method which could be used to detect which tab opened a new window? Nothing comes to my mind, maybe something could be possible using the chrome.webRequest API? I don't really know. For months I've been accepting the fact that a simple solution just wasn't possible, and helplessly waited for an update or something, but I never actually thought about asking here, because the problem looked above the competence of an average Chrome Extension programmer, but hopefully I was wrong.
UPDATE: The solution to inject a script inside the site and replace the window.open function with something else isn't viable: if an <iframe> is loaded without a src attribute, but with an already written DOM inside the srcdoc attribute, Chrome will not execute a content script inside it, even if the call to chrome.tabs.executeScript is made with allFrames: true, and even if the content script is declared inside the extension's manifest.
I came across the same problem and found the webNavigation.onCreatedNavigationTarget event that yields the source tab/frame id when a new window is opened.
Solution found from this post: Is it possible to determine a tab's opener within a Google Chrome extension?
Since you are already doing code injection this is what I would do.
Inject code to override window.open and have it window.postMessage to child window telling them who opened them. Also will need to inject code to listen to the effect of window.addEventListener('message', messageHandler) which will decided if they should window.close().
On second though I think I would just override window.open and not even open the child windows if you don't want to allow a give site to open windows.
hello i have a Django base app and one of its apps is chatting with customer service.
i want when the customer clicks on the the [x] icon or close the window, a small popup window should come up that include:
1.a string like "thank you, and we hope you can take time and answer the survey:"
2. a button that directs the customer to the survey page.
i have this part of the chatting app java script file:
window.onbeforeunload = function() {
window.open ("http://gadgetron.store/male_chatbot/popup/"); <= i have tried it and it doesn't work
$.ajax({
type: 'GET',
url: 'http://gadgetron.store/chatbot/run_python_clear_chatM/',});}
thank you,
I tried some thing like that before, but I think the browser disabled the popup customization. and note that you need configure the ajax call as synchronous (check this). you can use window.onunload event handler, and then small popup with confirm and cancel button, if you click on confirm you script will be executed and the tab will closed
For user experience reasons, browsers do not allow opening Popups during the unload-phase, which this event is part of. The only thing you can do is open a popup, asking the user to confirm that he really wants to leave the page. This is achieved by returning any non-empty string from the event callback (ie. return "Are you sure you want to leave?"; where you currently call window.open). The text inside this confirmation window can no longer be influenced by the application for most modern browsers.
For information regarding popups during the unload phase, have a look at the WHATWG Spec, most importantly the ignore-opens-during-unload counter which blocks document.open when set to any value greater than 0.
I need to spawn a tab using window.open('...', '_blank');
Then, I need that tab to CLOSE ITSELF, when the user click a button (button is in the new tab).
I have control over the codebase and server of both applications.
I tried the following:
in app#1:
window.tab = window.open('http://localhost:5007', '_blank');
in app#2:
function clickedButton() {
window.opener.tab.close();
}
Unfortunately I get security exception:
Error: Blocked a frame with origin "http://localhost:5007" from accessing a cross-origin frame.
How can I get around this error? Is there anyway I can use this library to overcome this? https://github.com/ternarylabs/porthole
I am simply going to quote documentation here, just for anyone who needs a reference click W3C and MDN.
function openWin() {
myWindow = window.open("", "myWindow", "width=200, height=100"); // Opens a new window
}
function closeWin() {
myWindow.close(); // Closes the new window
}
To break it down, the open and close functions use parameters than can be very useful, such as the URL, when desiring to open or close the current window, or in your case the opened window.
A practical example would be this stack overflow question. N
I hope it helps!
EDIT
To answer the OP's edit to the question: If it is a matter of triggering an event on a window which was opened, you can on the new window have an event handler which will trigger window.close() like so:
$('#anElementId').click(function() { window.opener.$('body').trigger('theCloseEvent', anyPassedData); })
However, if you truly do have control over the new tab, because it leads to a URL whose code base you are in control of, then it is only a matter of triggering an event there that you can trigger either once the window loads, or once you click a button... like so:
HTML
<button id="close-window">Close me</button>
Javascript/jQuery:
$(document).ready(function(){
$("#close-window").click(function(){
alert("ok");
window.close();
});
});
EDIT #2
To further extend the OP's edit, I want to include here an issue that can easily be encountered when attempting to trigger the opened window to close itself.
Quoted from How can I close a browser window without receiving the “Do you want to close this window” prompt?:
Scripts are not allowed to close a window that a user opened. This is considered a security risk. Though it isn't in any standard, all browser vendors follow this (Mozilla docs). If this happens in some browsers, it's a security bug that (ideally) gets patched very quickly.
None of the hacks in the answers on this question work any longer, and if someone would come up with another dirty hack, eventually it will stop working as well.
I suggest you don't waste energy fighting this and embrace the method that the browser so helpfully gives you — ask the user before you seemingly crash their page.
In other words, unless your webpage's script has control of the window which was opened, you should/cannot close said window. That is because the script running the window.close is not in control of the opened window.
EDIT #3
So many edits I know! But I am answering this in between my daily routine so bear with me. To answer the porthole.js question, it should be much more possible to do something with it, however you need to realize that you are working with iframes.
There is a significant difference when working with websites vs working with iframes, in which iframes are Widgets and websites (including mini sites) are given a URL. There are lots of considerations as well in terms of security and sandboxing, as can be seen on the portholejs demo here. This difference is also what does not allow you to work with different websites the way you want to initially.
My advise would be to evaluate your options with respect to your implementation: website to website vs website to widget.
Good luck!
Ok, I was able to accomplish this in the way I theorized by using porthole.js.
I believe this is the only cross-browser way to accomplish this without using hacks.
The solution consists of 2 apps (you must add code to both app for this to work).
app #1: http://localhost:4000
app #2: http://localhost:5000
In my case, I needed app#1 to spawn a need tab containing app#2. Then I needed app#2 to be able to CLOSE ITSELF upon clicking a button inside app#2.
If these apps were on the same domain (including same port), this would be relatively easy by saving a reference to the tab in app#1:
window.tab = window.open('...', '_blank');
And then accessing that reference from within app#2 via window.opener.tab.close()
However, for my case the apps needed to be on diff domains and doing this method resulted in a browser security exception. So instead, what I needed to do was host app#2 within an iframe inside app#1 (on some specific route, say /iframe), this way they ARE on the same domain as far as the browser windows are concerned, and now the second tab should be able to close itself using window.opener.tab.close().
However, a problem still remained because I needed the trigger to be a button INSIDE app#2 (aka a button inside the iframe), and since the hosting app and the iframe app are again not on the same domain, it seems like I would be back to square one... or maybe not.
In this case, porthole.js saves the day. You must load porthole.js into both apps (this is why you need access to both codebases). Here's the code:
in app#1 (http://localhost:4000/iframe)
// create a proxy window to send to and receive messages from the iFrame
var windowProxy;
window.onload = function() {
windowProxy = new Porthole.WindowProxy(
'http://localhost:5000', 'embedded-iframe');
windowProxy.addEventListener(function(event) {
//handle click event from iframe and close the tab
if(event == 'event:close-window') {
window.opener && window.opener.tab && window.opener.tab.close();
}
});
}
in app#2: (http://localhost:5000)
var windowProxy;
window.onload = function() {
windowProxy = new Porthole.WindowProxy(
'http://localhost:4000/#/iframe');
$('button').on('click', function() {
windowProxy.post('event:close-window');
});
}
And wa-lah, a self closing tab.
I'm stuck using a CMS that only gives me the ability to modify the content of the <body>, so when I want to redirect people, I've used this
<script type="text/javascript">
window.location = "http://www.example.com/"
</script>
So, yes, the page loads first, and then 5ms later, the redirect happens, and it's worked for all intensive purposes. Now, I'm wondering if I can use javascript to do something else.
Is it possible to open a new browser tab, with a specified URL, and then redirect the user back to the previous page, through Javascript?
Many thanks, SO.
EDIT - Whether it opens a new window or tab, to be honest, is not as important as it actually functioning. I need Javascript to determine the prior page (if possible), then open a new window/tab to a URL I specify, and then redirect the current window/tab to it's prior page. Some are saying that window.open only works on a click event, which will not work for what I am trying accomplish either... just fyi.
So, literally, without clicks, I need Javascript to do the following -
Determine the prior/previous/last page the user came from, store it as a variable
Open a new window or tab, to a specified URL
window.location back to the prior page, which I stored as a variable
Hope that makes sense.
Depending on the user's browser setting using window.open can open the new window in a new tab instead but you CANNOT directly control this through the browser. It is all down to the user's settings.
To open a new window:
window.open("http://www.google.com", "windowName", "window options (optional parameter)");
Then simply use:
history.back();
You can also use the referer property:
var previousUrl = document.referrer;
For more info on window.open, see: http://www.javascript-coder.com/window-popup/javascript-window-open.phtml
For more info on the document.referrer property, take a look at: http://www.netmechanic.com/news/vol4/javascript_no14.htm
In order to process special URLs in an already opened web application I use this approach:
the user receives a special URL in an email (alarm notifications)
the URL opens a small helper web page (H) with JavaScript code that temporarily sets a session cookie
the main web application (M), which is already open in another tab/window, recognizes this and handles the request after deleting the cookie
the helper web page (H) identifies this as a success and is now useless and should be closed.
This all works fine except for the helper window (H) remaining open.
Of course there is a small text saying "please close this window now" but it would be perfect if it could do this automatically.
window.close() causes a confirmation dialog in IE and FireFox just ignores the command. I understand this is because the window has not been opened using window.open().
Similarly, calling window.focus() in the main window does not do anything, either.
Does anyone have an idea how to accomplish this anyway? At least, automatically focusing the main window without closing the helper window would be better than nothing.
Of couse I'm also open for other solutions to handle e-mail links in an already open web application... :)
Note the web application (and the helper page of course) are on a HTTPS server.
In some browsers, a window can only be silently closed through javascript if it was opened via javascript (for security purposes).
This code is a hack to get around this security measure:
// open a new window, replacing the current one
window.open('', '_self', '');
// close the current window, which was now technically opened via javascript
window.close();
Use at your own risk. These measures are in place to prevent you from doing annoying/malicious things to visitors of your page.