Is it possible to stop all the requests/scripts that are happening on a page, when the refresh button is hit?
I have a $.ajax request that takes a few minutes. I have tried to do window.stop() in the unload event; I have tried xhr = $.ajax(...); and xhr.abort(); and any other methods found over the internet and nothing works.
Is this even possible? Why the browser still waits for that request to finish and send back a response and not refresh the page?
LATER EDIT (SOLVED): it seems that the waiting problem is actually from the server. If in the ajax call, the script uses the SESSION then the web page will freeze until the request is finished, even if we abort the xhr.
Why is that? Explanation:
Session data is usually stored after your script terminated without the need to call session_write_close(), but as session data is locked to prevent concurrent writes only one script may operate on a session at any time. When using framesets together with sessions you will experience the frames loading one by one due to this locking. You can reduce the time needed to load all the frames by ending the session as soon as all changes to session variables are done.
Maybe try canceling right before refresh as in here?
window.onbeforeunload = function(event) {
xhr.abort();
};
Related
I've been searching for any reasonable example of a situation, when synchronous AJAX makes sense. I've found this SO question, where the author mentions window.onbeforeunload and claims, that "the request would never stop" if the AJAX call was asynchronous.
Can anybody explain this? I mean - window.onbeforeunload is fired when the user wants to close the tab. What had to be going on to make the tab still alive, even though somebody clicked to close it? Can somebody give more specific example?
He didn't say the request will never stop; he said it will never complete. That is, your code has no hope of ever getting the response back, because the execution environment (the window) would disappear from existence before that happened.
The tab will close when window.onbeforeunload exits with a truthy value. Thus, as long as it is running, the page is waiting for the return value, and not closing. This allows a synchronous AJAX to be sent, and for the response to be received and processed. If the request is asynchronous, the code constructs XHR object, then exits, and the page (and your code) goes away.
I have never tested this, but the answerer apparently believes (and I don't think it unreasonable) that the page might not stick around long enough for an async XHR to even be sent, let alone to receive a response. Thus, if you want to be sure the server receives the information that the user closed the page, you want to have the request synchronous.
What had to be going on to make the tab still alive, even though somebody clicked to close it? Can somebody give more specific example?
Sending a synchronous XMLHttpRequest on unload is the only way to guarantee delivery of session data when a user-agent unloads the page (and may never re-visit your site again). There are two specific cases for this:
Tracking - Tracking and reporting the total session time for a user's page visit.
Batching - Coalescing and deferring delivery of batched session data to reduce the number of server requests.
The Beacon spec (navigator.sendBeacon) was designed to optimize this specific case, making it possible to send asynchronous requests guaranteed to still complete even after the page unloads.
I have tested this and it seems like even if the page unloads, the async action completes regardless if the tab is closed or if the tab navigates to a new url. The server it's calling to however is pretty snappy.
What is the process behind the scenes when it comes to async processes running and tabs being closed - at which point will the browser just call it quits on an async process that the page has started?
You cannot rely on the behavior of async calls from within onbeforeunload and onunload between servers.
We had an app that ran with an Apache server- Windows on our dev environment, and Unix on the release. It turns out that when the server was configured to handle requests in threads- default for our Windows/dev boxes- the Ajax would always complete; when it was configured to handle requests in processes- default for our Unix/prod environment, it would always cancel!
What happens is that the Ajax request fires, and then the browser unloads the page, which closes the connection for the Ajax reply. We set up a test where the Ajax call would execute a 4-second "sleep" on the server to avoid any timing issue. It looked like with a threaded back-end, Apache did not notice the client closing the connection until after it returned from the "sleep", whereas with the child-process backend, it aborted the Ajax call immediately.
The answer is to use synchronous requests in your on[before]unload event handler. That will keep the page open until the request completes. That does mean an additional delay when the page switches/reloads/goes back...
...and also you have no guarantee that the next page will see the results of that request- it seems that some browsers will GET the next page before firing the onunload event! But that's a topic for another question.
This question already has answers here:
JavaScript, browsers, window close - send an AJAX request or run a script on window closing
(9 answers)
Closed 6 years ago.
Is there any possibility how to send AJAX after close the browser window?
I have a browser game with movement in JavaScript (jQuery) and if I send Ajax after each movement it would be difficult for the server. So I want to send one AJAX when user close the window (or bookmark).
It must be functional in all modern browsers.
Thank you for answers
I'd suggest you update the server on some sort of timer so the server never gets too far behind in knowing what state the client is in (perhaps every 60 seconds when the client is active), pausing server updates when the client is not active.
Then, in your user interface, put some obvious user interface elements for Close or Stop that encourages the user to shut-down that way and then update the server when either of those buttons are hit.
Then, you can also hook the unload event for the page and send one last ajax call then. But, this is not called in every case or supported in all browsers so this would be done in addition to the two previous techniques.
I don't think there is a practical way to do it... but there is definitely a solution to your problem.
You can send your request either at some time interval or when the game arrives at a particular stage.
We're not seeing the complete scenario so please evaluate a bit more so I or someone else can help.
If possible.. I would add a "Save State" or just "Save" button. So the user knows that if he doesn't hit "Save" nothing will be "Saved".
You can try window.onbeforeunload e.g.:
function saveGame(e) {
if (!e) e = window.event;
//Ajax here
}
window.onbeforeunload = saveGame;
You can't send any ajax request after closing browser window. But you can use onUnload event for send ajax request when user click close button of the window.
I can suggest this:
invoke window.onunload (pay attention to firefox!) and store the current location in the server. important: make this async call.
in the server save the state of the user (leaving a page)
write a code in the global request event handler and query this state.
you can launch threads in the server to invoke the final unload (say, after 5 sec) no new request from the client
I know these steps are hard to implement, but they address your problem and solves it.
I need to have my web page periodically poll the server for new information every 10 seconds. I have a timer (setTimeout) setup to call my AJAX function to get the data. On completion, the AJAX function sets the timer for another 10 seconds.
The problem is that Firefox continuously displays the "Page Loading Indicator" (Throbbing).
How do I periodically poll for new data, but stop the throbbing?
P.S. If I hit the ESC key, the throbbing stops and the timer keeps going, so that is a crude workaround. I need a way to not involve/confuse the user.
There are a few techniques to "background" loading where you don't display the status bar or cursor changes:
XHR Eval and XHR Injection are the only techniques that do what you want for FF (and all other browsers). You can see the test/example site here:
http://stevesouders.com/hpws2/couple-xhr-injection.php
You can also look at WebSockets.
It will be faster and there will be no need in timer.
This question already has answers here:
JavaScript, browsers, window close - send an AJAX request or run a script on window closing
(9 answers)
Closed 6 years ago.
I would like the browser to keep the page open until the ajax requests are sent. This is what I imagine it would look like
var requestsPending = 0;
window.onbeforeunload = function() {
showPleaseWaitMessage();
while(requestsPending > 0);
}
// called before making ajax request, atomic somehow
function ajaxStarted() {
requestsPending++;
}
// called when ajax finishes, also atomic
function ajaxFinished() {
requestsPending--;
}
Unfortunately, JS doesn't do multi-threading. To my understanding, the callback (ajaxFinished) would never be executed because the browser would try to wait until the while loop finishes to execute it, and so the it would loop forever.
What's the right way to do this? Is there maybe a way to force JS to evaluate the next thing in its to-do list and then come back to the while loop? Or some syntax to "join" with an ajax call? I'm using DWR for my ajax.
Thanks,
-Max
Edit Based on your comment below, a revised answer:
If you want to block until a previously-initiated request completes, you can do it like this:
window.onbeforeunload = function(event) {
var s;
event = event || window.event;
if (requestsPending > 0) {
s = "Your most recent changes are still being saved. " +
"If you close the window now, they may not be saved.";
event.returnValue = s;
return s;
}
}
The browser will then prompt the user to ask whether they want to leave the page or stay on it, putting them in control. If they stay on the page and the request has completed while the prompt was up, the next time they go to close the page, it'll let them close it without asking.
Note that on modern browsers, your message will not be shown; instead, the browser will use a generic message. So on modern browsers, returning any non-blank string is sufficient. Still, you may want to return a useful string (such as the above) in case your user is using an obsolete browser that will still show it.
More on asking the user whether to cancel close events here and here.
Old answer :
Ideally, if possible, you want to avoid doing this. :-)
If you can't avoid it, it's possible to make an Ajax request synchronous, so that it blocks the onbeforeunload process until it completes. I don't know DWR, but I expect it has a flag to control whether the request is synchronous or not. In the raw XmlHTTPRequest API, this is the third parameter to open:
req.open('GET', 'http://www.mozilla.org/', false);
^ false = synchronous
Most libraries will have an equivalent. For instance, in Prototype, it's the asynchronous: false flag in the options.
But again, if you can possibly avoid firing off Ajax requests as part of the page unload, I would. There will be a noticeable delay while the request is set up, transmitted, and completed. Much better to have the server use a timeout to close down whatever it is that you're trying to close down with this. (It can be a fairly short timeout; you can keep the session alive by using asynchronous Ajax requests periodically in the page while it's open — say, one a minute, and time out after two minutes.)
In short, you cannot (and shouldn't) do this. If a user closes the browser, it's closing...no unload style events are guaranteed to finish, and something doing AJAX with involves latency is more unlikely to finish.
You should look at firing your events at another point, or change the approach altogether, but making an AJAX call in an unload event is going to unreliable, at best.
As an addendum to the above on the shouldn't part, think about it this way, how many tabs do you usually have open on any given window? I typically have 4-6 chrome windows open with 5-12 tabs each...should my browser window hang open because 1 of those tabs wants to make some AJAX request I don't care about? I wouldn't want it to as a user, so I wouldn't try and do it as a developer. This is just an opinion of course, but food for thought.