Allowing an AJAX request to finish after the page is closed - javascript

I am currently developing a chat using your typical everyday web programming languages (JavaScript, PHP etc..). The chat is currently fully functional. However, there are several issues that I have yet to solve successfully. One of which being a cross-browser issue.
I am trying to run an AJAX request when a user closes the tab. The PHP for this request looks something like this:
date_default_timezone_set("America/New_York");
session_start();
unset($_SESSION["onpage"]);
if ($_POST['logout'] == "false") {
sleep(5);
if (isset($_SESSION["onpage"]) || !empty($_SESSION["onpage"])) die();
}
...
...
And the AJAX being:
$.ajax({ // this is jQuery
type: "POST",
url: "offline.php",
data: {
logout: out ? 'true' : 'false'
},
success: function (data) {
document.location.reload();
}
});
Basically, when a user closes the tab (in that case $_POST['logout'] will equal false), the request should not finish until the 5 seconds (sleep(5)) have finished. This is because I do not want this request to be fired when a user simply refreshes the page, only when it is confirmed that he left the page.
This is where the cross-browser issue comes in. The functionality I want to achieve works perfectly fine in Safari. This being that on refresh, the request doesn't finish, but if I close the tab, after 5 seconds it does what it is suppose to do and completes. However, on chrome when I hit refresh, refresh itself does not complete until the 5 seconds are over already over which means the request completes regardless. Chrome is waiting for the AJAX to be completed while Safari does not.
Is there any simply fix to this issue?
Edit:
I have tried the following code from a suggestion in the comments:
var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
if (isChrome) {
var formData = new FormData();
formData.append("logout", "false");
navigator.sendBeacon("offline.php", formData);
} else {
$.ajax({ // this is jQuery
type: "POST",
url: "offline.php",
data: {
logout: 'false'
},
success: function (data) {
document.location.reload();
}
});
}
It however did not successfully work.

Related

AJAX call after onbeforeunload event is not working, only when refreshing the page

I am trying to handle the onbeforeunload event so that when the user closes the browser tab, a message will appear saying something like: Are you sure you want to leave this page? (The default browser message it's okay).
I was able to achieve something like this using this code:
window.onbeforeunload = function() {
return "";
}
But I realized that if I close the tab without refreshing the page beforehand, no message will appear. If I open the page, refresh (I can see a message from the browser) and then I click on close the tab, then I'm getting a message from the browser asking if I'm sure about leaving the page. If I don't refresh first, nothing happens.
I would like to do something like this (pseudo-code):
If user refresh the page:
Nothing happen
If user close the tab/browser:
Show browser alert message + run ajax call in the background.
I tried something like this but also didn't work:
window.onbeforeunload = function() {
$.ajax({
url: '/some-view/',
type: 'get',
dataType: 'json',
success: function () {
console.log("it works!");
}
});
return "";
}
Could someone provide a valid example for 2021? Almost all old stackoverflow questions are no longer supported by modern browsers and the methods are deprecated.
The problem is that ajax is an async call, and it won't wait for it to return anything. You can try to make your ajax call synchronous:
window.onbeforeunload = function() {
$.ajax({
url: '/some-view/',
type: 'get',
dataType: 'json',
async: false,
success: function () {
alert("it works!");
}
});
return "";
}
There is no reliable way to distinguish between reload and close. Page is being unloaded in both cases.

Closing lightbox sometimes fires faster than onblur() on input

I'm running this code on blur() on an input. It works great, as long as you don't click on anything that takes you to a different page or closes the lightbox (div in an overlay) where the ajax function and input was loaded from, since there is a chance that the ajax script will be aborted. I get that it may be hard to make sure that the content is saved on blur() if you close the browser window, but is there any way I can wait until the ajax request (and any link click) is finished before I close the lightbox (or move on to a different page)?
I guess another option would be to have on input() instead/as well as on blur(), but then I get a lot of ajax requests and need to start throttling right? My lightbox plugin (fancybox) has an event called beforeClose, can I run something in there that checks if the ajax request was sent?
Please let me know if I'm thinking about this the wrong way. I know that async false is not really recommended, but maybe what I need?
$.ajax({
type: "POST",
dataType: "json",
url: "?a=ajax",
data: { value: $self.val() },
error: handleError
}).done(function(data) {
if( data == "0" )
{
// no success
}
else
{
// success
}
});

Ajax request within partial view loaded through another Ajax request does not work properly in IE 11

Following is the exact scenario in my ASP.NET MVC application:
The parent page is having 3 tabs, and following javascript is written to bind click event to each of the tabs:
Each function invokes a controller action (specified in the data-url attribute), and renders the result in the partial view which is expected to be displayed within "ContactMainContainer" div.
jQuery(document).ready(function () {
$('#ContactTabs a').on('click', function () {
var dr = $(this).closest('li');
var url = $(this).attr("data-url");
if (url != undefined && url != '') {
var projectDetailTabModel = $("#ContactID").val();
$('#successDiv').hide();
$('#errorDiv').hide();
$.ajax({
type: "POST",
url: getUrlWithTabId(url),
data: projectDetailTabModel,
success: function (result) {
$('#ContactMainContainer').html(result);
},
error: function (errMessage) {
if (errMessage != null && errMessage.length > 0) {
$("#errorDiv").show();
$("#errorText").html(errMessage);
}
}
});
}
});
});
Contents of one of the partial view is built using javascripts (mostly ajax calls). (I am unable to put the whole javascript here as it is a client project and confidentiality agreement, and the javascript library is too large to place here).
The issue is that when a user navigates to that particular tab (having Ajax call), it takes a long time to execute and render the result. But after that if user clicks on any other tab the browser stucks and hangs for infinitely.
This issue is only in IE11, and works very well in all other browsers (Chrome, firefox, and all).
Could anyone please suggest what could be the reason?
It's a caching issue and IE is well known for caching. You need to make sure in your Ajax call to set the catching as false
Setting the cache property in an AJAX call
$.ajax(url, {
dataType: 'json',
cache : false,
//Other things ...
}
I prefer to use cache buster in the request URL, that is adding the current timestamp as parameter, so that it cant be cached

SyntaxError: Unexpected token else

So I don't have a whole lot of experience with Javascript but I've done pretty well in the past. I have this website where I'm trying to run 'geoip' to pull two iso's to take to a certain page, this I've gotten to function perfectly. However, if said ISO completes a purchase a Thank You page is presented to them, but goes away because the 'geoip' is still in place. I've tried running a 'return' but can't seem to get the hang of it. In Sublime Text 3 it looks fine, any help would be GREATLY appreciated. Here's my code:
$.ajax({
url: 'https://freegeoip.net/json/',
type: 'POST',
dataType: 'jsonp',
success: function(location) {
// If the visitor is browsing from Australia or New Zealand.
if (location.country_code == 'AU' || location.country_code == 'NZ') {
// Redirect visitor to the purchasing store.
window.location.href = 'http://example.com/order-international/';
else {
location.country_code == 'AU' || location.country_code == 'NZ' === window.location.href = 'http://example.com/thanks-international/') {
return; //stop the execution of function
} else {
//keep on going
}
}
}
});
Two things:
First, when I cleaned up your code formatting, it became fairly clear that there are some misplaced {} (at least). I've tried to guess from the comments what you were really trying to do below.
Second, you've said you want to stop execution of "the function," so I'm guessing this ajax call is in some function somewhere.
What you do is make the rest of the function a function, and then call that from the ajax success handler if you want it to run, or don't if you don't. E.g.:
function yourOuterFunction() {
$.ajax({
url: 'https://freegeoip.net/json/',
type: 'POST',
dataType: 'jsonp',
success: function(location) {
// If the visitor is browsing from Australia or New Zealand.
if (location.country_code == 'AU' || location.country_code == 'NZ') {
// Redirect visitor to the purchasing store.
window.location.href = 'http://example.com/order-international/';
} else {
// keep going
keepGoing();
}
}
});
function keepGoing() {
// The part you want to do after you have the ajax result
}
}
I didn't quite know what you were trying to do with your thanks-international link, but hopefully that gets you headed the right way.

Send AJAX to server beforeunload [duplicate]

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.
So supposedly starting at Firefox > 4, binding the window jQuery object to beforeunload doesn't work anymore.
What'd I'd like to do is submit an AJAX post to delete my server's memcache data.
When I refresh the only open tab, I can see that the beforeunload event is called in both firefox and chrome with the following code as evidenced by the console.log message, "firefox/NON-firefox delete". The problem is that I never see the console.log message "memcache delete" indicating that my server never saw the $.ajax request.
I realize it is bad to do browser sniffing and that there is no difference between what's included in the if and else statements. I'm merely showing code for what I've tried unsuccessfully in Firefox.
Anyone have any ideas?
$(window).bind('beforeunload', function(){
if(/Firefox[\/\s](\d+)/.test(navigator.userAgent) && new Number(RegExp.$1) >= 4) {
console.log('firefox delete');
memcacheDelete();
return null;
}
else {
console.log('NON-firefox delete');
memcacheDelete();
return null;
}
});
function memcacheDelete() {
$.ajax({
url: "/memcache/delete",
type: "post",
data:{},
success:function(){
console.log('memcache deleted');
}//success
}); //ajax
}
Ajax is asynchronous.
When you refresh (or close)your browser, beforeunload is being called. And it means as soon as beforeunload is finished executing, page will refresh (or close).
When you do an ajax request, (since its asynchronous) javascript interpreter does not wait for ajax success event to be executed and moves down finishing the execution of beforeunload.
success of ajax is supposed to be called after few secs, but you dont see it as page has been refreshed / closed.
Side note:
.success() method is deprecated and is replaced by the .done() method
Reference
Just for sake of completion, here's what I did, thanks to #Jashwant for the guidance:
I noticed that this other SO Q&A suggested the same solution.
The KEY is the async:true(false) in the $.ajax call below:
$(window).bind('beforeunload', function(){
if(/Firefox[\/\s](\d+)/.test(navigator.userAgent) && new Number(RegExp.$1) >= 4) {
console.log('firefox delete');
var data={async:false};
memcacheDelete(data);
return null;
}
else {
console.log('NON-firefox delete');
var data={async:true};
memcacheDelete(data);
return null;
}
});
function memcacheDelete(data) {
$.ajax({
url: "/memcache/delete",
type: "post",
data:{},
async:data.async,
success:function(){
console.log('memcache deleted');
}//success
}); //ajax
}

Categories

Resources