I am trying to send some requests to the database when the window is unloaded (i.e. when you refresh the page). For some reason, only on Safari, the client side code gets executed, but the request to the server never goes through. When I step through the code manually in the debugger, the server does get the request and processes it fine.
Anyone know why this is happening?
window.onbeforeunload = function() {
console.log("inside on before unload");
var requestParam = new a.ListRequest();
requestParam.setAction('set_delete');
var callback = function(isSuccess, response) {
if (isSuccess) {
//do something
} else {
// do something else
}
};
// Sends request to server
a.Fetch.list(requestParam, callback);
}
I am trying to send some requests to the database when the window is unloaded (i.e. when you refresh the page). For some reason, only on Safari, the client side code gets executed, but the request to the server never goes through. When I step through the code manually in the debugger, the server does get the request and processes it fine.
Anyone know why this is happening?
window.onbeforeunload = function() {
console.log("inside on before unload");
var requestParam = new a.ListRequest();
requestParam.setAction('set_delete');
var callback = function(isSuccess, response) {
if (isSuccess) {
//do something
} else {
// do something else
}
};
// Sends request to server
a.Fetch.list(requestParam, callback);
}
Share
Improve this question
edited Dec 11, 2015 at 20:56
petranaya
asked Dec 11, 2015 at 20:36
petranayapetranaya
7791 gold badge6 silver badges23 bronze badges
4
- Without seeing your code, the only guess I could give is.. you have a bug in your code. – Lil Devil Commented Dec 11, 2015 at 20:49
- It works on Chrome and Firefox though. I'll add some sample code too – petranaya Commented Dec 11, 2015 at 20:50
- What do you send to the server? Also why do you want this sent onbeforereload? – Pablo Jomer Commented Dec 16, 2015 at 9:40
- I'm sending a request to the server to update the database and I want this to happen before the page unloads. The server then sends a response back saying failed or succeeded. (this is all asynchronous) – petranaya Commented Dec 16, 2015 at 16:30
4 Answers
Reset to default 5 +50Likely the request that happens in the Fetch call is asynchronous and Safari is not waiting for it to finish before moving on to the next page/closing the tab. If you can make the call synchronous it should work. Keep in mind that synchronous calls are generally discouraged and deprecated in some tools.
This answer related to Jquery has a good explanation of synchronous calls: https://stackoverflow./a/11755262/1341437
You can use Beacon API
(FF, Chrome, Opera):
window.addEventListener('unload', logData, false);
function logData() {
navigator.sendBeacon("/log", analyticsData);
}
User agents will typically ignore asynchronous XMLHttpRequests
made in an unload handler. To solve this problem, analytics and diagnostics code will typically make a synchronous XMLHttpRequest
in an unload
or beforeunload
handler to submit the data. The synchronous XMLHttpRequest
forces the User Agent to delay unloading the document, and makes the next navigation appear to be slower. There is nothing the next page can do to avoid this perception of poor page load performance.
Using the sendBeacon()
method, the data will be transmitted asynchronously to the web server when the User Agent has had an opportunity to do so, without delaying the unload or affecting the performance of the next navigation.
You can do it with jQuery.ajax by set the async property to false async:false
window.onbeforeunload = function() {
$.ajax({
// Query to server
async:false,
method: "GET",
url: "your.page",
data: { param1 : "value1" }
}).done(function(jqXHR, textStatus) {
// Verify good data
// Do stuff
alert( "Request done: " + textStatus );
}).fail(function( jqXHR, textStatus ) {
alert( "Request failed: " + textStatus );
});
}
As @craigts said, the browser is gone before the ajax call can be returned. You might get a few more seconds on that page.
window.onbeforeunload = function(e) {
return 'Dialog text here.';
};
However, your users will find this annoying.
2nd option, find another event instead of waiting for the page unload. Capture your data continuously. Capture it onChange. Will the user be using a link to continue? If so you can hijack the link with cancelEvent() and then continue after the ajax has returned.