My application has got several pages. On some pages I have given a back button on other pages it's not given (client's requirement). Now on a particular page, I have a list of choices (choices are image slides using jQuery plugin) to be selected by the user. Selecting a choice takes the user to next page. And now I want to get the same page with same selected choice as highlighted on clicking the browsers back button. On clicking the browsers back button, I guess the page is reloading loosing the cookie values i.e. when I select an image from my image set it takes me to another page. On clicking the browser back button, I wanted to get that page with same image selected from that set.Is there any work around so that I can get the selected values also on browser back.
Another plugin do that:
jQuery BBQ leverages the HTML5 hashchange event to allow simple, yet powerful bookmarkable #hash history. In addition, jQuery BBQ provides a full .deparam() method, along with both hash state management, and fragment / query string parse and merge utility methods.
http://benalman.com/projects/jquery-bbq-plugin/
You could utilize the onunload event, which almost all major browsers* will fire, when the back/forward/refresh button is used. Let the onunload event handler synchronously send an AJAX request, containing all the values needed to restore the current page state, to a PHP script:
$(window).unload(function() {
// Insert your code here to collect all values
// necessary to save a restorable state of the
// current page.
//
// var pageState = {
// page: host.pathname,
// :
// };
$.ajax({
type: "POST",
async: false,
url: "http://mydomain.com/mysave.php",
data: jQuery.param(pageState),
error: function(jqXHR, textStatus, errorThrown){
// your code
}
success: function(data, textStatus, jqXHR){
// your code
}
});
});
Let the PHP script save the received page state somewhere (e.g. session, database, etc.), so it's available, when you're about to generate a page you would like to be restored to a previous state.
Be aware, that this solution has a possible disadvantage.
The synchronous request is used to give the server a real chance to receive and process the request completely. An asynchronous request would return immediately, thus already loading the new page and maybe cancelling the asynchronous request running in parallel, before it has been completed (or even sent).
Otoh synchronous requests block (freeze the browser, user cannot do anything) until the server responds. In case your server does not respond, this would result in a deadlock. Unfortunately there is no way to cancel a synchronous request on client-side (at least none that I'm aware of), so you should always keep synchronous requests short as possible (server side processing time). And to make sure, that you have a fast and reliable server, but you should always have that anyways^^.
*Be aware though, that some browsers (e.g. Opera) do not fire the onunload event, when specific browsers button are used.
Related
first post here :)
I have a mobile app (Phonegap) that sends an ajax request to a PHP server, say a friend invite. When receiving the request, a few things have to be done (create links, authorisations, send e-mails, etc) which take a long time (5 sec). During that time, the user on the app is looking at a spinner, waiting for the ajax request to complete.
Ideally:
return a confirmation "Friend request received", without waiting for the process to finish.
No Cron jobs because waiting 1 min is too long.
Something simple (Gearman is scary)
On the app :
$.ajax({
url: 'http://www.my_site.com/action.php',
type: 'POST',
data: "my_guid="+my_guid+"&friend_guid="+friend_guid,
dataType: 'json',
success: function(json) {
// Send confirmation
},
error: function(json) {
// Show error
}
}
On the server (PHP):
$my_guid = $_POST['my_guid'];
$friend_guid = $_POST['friend_guid'];
// return here confirmation to the app
veryLongFunction($my_guid,$friend_guid); //continue executing long function
Simple, don't show the spinner.
It's asynchronous anyway
Just don't show the spinner. The request itself is asynchronous. The user can continue using the page while the request is waiting in the background for a response. Only when the response is received, the success handler kicks in.
Alternative feedback
So instead of showing a spinner overlay, I'd show a small notification at the top of the page saying 'Saving....', something that doesn't block sight too much, maybe even just a small icon or animation in a corner, or on top of the button they clicked (see snippet below) to do the action.
Then, when the response is received show a more visible notification indicating success or error.
Handling navigation
Navigating away from the page would end the request. That doesn't mean that the PHP script is ended right away, but if you start outputting information and sending it to the client, your server will notice the connection is gone and it will kill the PHP script. You can prevent this and make PHP finish the request by using ignore_user_abort(true).
Minor detail: while the friend invite is being saved, you cannot really see that, so if you navigate to another page that also shows the friend invite button, it's tricky to make that show the right status. One solution might be to set a 'saving' flag as soon as you start saving the invite, but personally I wouldn't go that far. Just make sure you script gracefully handles a duplicate save and hide the collision from the user.
Prototype of inline indicator
Here is a small snippet to show what I mean by showing it inline. It doesn't do an actual request, but simulates it using setTimeout. You can click each button and you can continue using the page. Instead of showing a big spinner, I just show a text in the button you just clicked, so you know which friend request you are saving.
So this way, there is more feedback to the user (the exact name that is saving), the feedback is less obtrusive (it's only there in the place of the button that should not be clicked anymore anyway), and you can show the response in the same place, or choose to show a notification (or both).
$('button').on('click', function(){
// Button is clicked. Disable and show an indicator.
var button = $(this);
button.prop('disabled', true);
button.text('saving...');
// Simulate the request that takes 5 seconds.
setTimeout(
function(){
// Simulate success
button.text('Saved!');
button.css('color', 'green');
}, 5000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>John <button>Send friend request</button>
<li>Jane <button>Send friend request</button>
<li>Jack <button>Send friend request</button>
<li>Janet <button>Send friend request</button>
I have application with huge ajax. Some times ajax not working properly when user close browser. This happens because there are many 3rd party add on installed in their browser which stop (may be) work ajax properly.
Now I have no control over users, so unable to make users careful about their browser. Now what can i do in this situation. Is there any way to force ajax to work even with bad extension installed in browser?
Following code not work when bad extensions (like ask toolbar,alibaba news ticker etc) installed in browser
window.onbeforeunload = function () {
$.ajax({
url: site_url + '/agent/send_offline',
type: 'post',
cache: false,
async: false,
...
});
};
You cannot rely on always being able to do an ajax call when the user leaves your page. That just isn't something you can reliably do in a browser. It may work sometimes, but is not guaranteed to work in all possible ways that a web page can be closed.
There are some work-arounds:
You can maintain a websocket connection from your page to your server and when the user leaves the page, the socket will be automatically closed by the browser and your server will then know the user left the page.
You can have your page poll your server every few minutes with a simple ajax call and when the server no longer gets a polling ajax call, then it knows that the page has been closed.
you can do it by storing cookie in browser to call your page after every miniute where ajax code is placed. try this angle
How can I track how long a user stays on a page before they request another or simply leave the site?
Basically, I want to do a check, if a user stays on the page for 20 minutes or longer, then do something.
I believe this would require php and javascript, but I am not exactly sure how to accomplish it.
Maybe using this $_SERVER in php to get the time of execution, and then get a timestamp when the user clicks somewhere else and simply compare the two?
You can do all this with simple javascript.
For a single page:
window.setTimeout(function(){
// Do stuff after 20 minutes of loading the page
// Then using jQuery you can call a PHP script to do stuff like so:
$.ajax({
url: '/myScript.php',
method: 'POST',
success: function(result){
//The request was successful and the output is stored in a variable: result
},
complete: function(){
//Do stuff when the request is completed (Ignores if success or not)
},
beforeSend: function(){
//Do something before the request is sent
}
});
}, 20 * 60 * 1000); //This is in milliseconds that's why I use the equation
For multiple pages:
I suggest you set a cookie with the time a user hits a page and on each page check if the cookie exists. If it exists run a query every x ammount of seconds to see if the 20 minutes have passed since the cookie has been created.
For full Ajax documentation head to: http://api.jquery.com/jQuery.ajax/
I've put some work into a small JavaScript library and service that times how long a user is on a web page. It has the added benefit of more accurately (not perfectly, though) tracking how long a user is actually interacting with the page. It ignores time that a user switches to different tabs, goes idle, minimizes the browser, etc. The Google Analytics method has the shortcoming (as I understand it) that it only checks when a new request is handled by your domain, which is not always accurate. It doesn't consider if someone is no longer viewing your page, has minimized the browser, has switched tabs to 3 different web pages since last loading your page, etc.
For reference - no solution is perfect. But hopefully this one provides value, too. You can implement the Javaacript API and gather the statistics yourself or you can use the service which does it all for you.
http://timemejs.com
An example of its usage:
Include in your page:
<script src="https://timemejs.com/timeme.min.js"></script>
<script type="text/javascript">
TimeMe.initialize({
currentPageName: "home-page", // page name
idleTimeoutInSeconds: 15 // time before user considered idle
});
</script>
If you want to report the times yourself to your backend:
xmlhttp=new XMLHttpRequest();
xmlhttp.open("POST","ENTER_URL_HERE",true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
var timeSpentOnPage = TimeMe.getTimeOnCurrentPageInSeconds();
xmlhttp.send(timeSpentOnPage);
TimeMe.js also supports sending timing data via websockets, so you don't have to try to force a full http request into the document.onbeforeunload event.
I want a clarification about AJAX on something I was thinking about...
AJAX is said to be asynchronous - if you want it to be - meaning that if a javascript is run while a page loads and in that an AJAX call is executed the page will continue to load while the server process the AJAX request... So is it safe to assume that it can be liken to a pseudo-parallelism?
Now, what about two different javascripts making an AJAX call consequently. That is, while the page loads it encounters two js function one after the other each making an AJAX call each. Because they are different js functions/ or two different js files do they have to wait for the functions to return before they move on? I think that is the case...
And finally the real question I have... If I have a js function called and in that function I palce TWO AJAX calls then will they be processed semi-simultaneously... Because I was trying something on a webpage of mine and by accident I placed two AJAX calls one after the other and I think that was the reason I had some unexpected results. Unfortunately I was in a hurry to deliver so I didn't pursue it but I was wondering if it world like that, because it would be very convenient for some cases...
Somethign like this
function finalizeReservation(){
var request = $.ajax({
type: 'POST',
url: './scripts/php/reserve.php',
data: {
},
dataType: "json"
});
request.done(function(data,textStatus,jqXHR) {
});
request.fail(function(jqXHR, textStatus, errorThrown) {
});
var request2 = $.ajax({
type: 'POST',
url: './scripts/php/reserve.php',
data: {
},
dataType: "json"
});
request2.done(function(data,textStatus,jqXHR) {
});
request2.fail(function(jqXHR, textStatus, errorThrown) {
});
}
Simply curious.
I was thinking it because I have a web page that records reservations. Before finalizing a reservation though the guest can see the details and think about it. At that period the slot in the database is set to pending and making unavailable to another guest so they don't clash or enter in race conditions (i.e while thinking about it the other finalizes it and so when he tries to finalize it himself he cant or if was careless in the code also finalizes it). The problem is in the guest behaviour, although I have tried to capture all events of the refresh, backpage, exit tab, close window kind so the slot doesn't stay in a pending state if the guest for some reason doesn't close the form the correct way (cancel) not all are captured in all browsers. So I though about making a time limit in the server and if it exceeds it and the state is still pending the state is reversed to free (I have the form on a minute timer, after the minute goes it automatically closes and frees the slot). The problem is that the hosting server doesn't support chron jobs although I don't know much about them so I am not sure how much help they would be and the mysql doesn't support schedulers.
So i thought about making two ajax call and the one to be a timer that will check the state of the slot after some time passes and act accordingly.
Any thoughts are appreciated.
Sorry for the long post.
You don't have a specific question about Ajax, but you do seem to have a pretty good understanding of it and everything you said is correct. At least with jQuery, it's asynchronous by default and unless you use Deferred there is no guarantee that code that executes after the ajax call won't complete before the ajax call.
Your actual question seems to be about how to handle stale locks for the reservations. A couple suggestions:
Move to another shared host. I pay $15 a year for a shared host that allows cron jobs.
Whenever someone visits the page, check all locked reservations and if they are old enough assume the lock is stale.
Another ajax call won't help. What if they close the page? You could try using onbeforeunload, to alert a dialog that will remove the lock, but that's very intrusive.
the execution of code after the ajax functions will continue, without waiting for the ajax functions to complete, unless the code that follows is in the callback of the ajax function.
So I have a bookmarklett that seems to not work on some sites.
Here's what happens. The bookmarklett (exists on your bookmark bar) fires a javascript sequence that will construct a div with content on any page you are currently on.
Once the div is constructed, it will send an ajax GET request to a php page on my server (that is, the page the bookmarlett is loaded on is not within my server, this is somewhere else, ajax requests data from my server to be sent to the website the bookmarklett is loaded into).
Apparently, I have not seen this error myself, I was told that the ajax call failed to be received, so no dynamic data was passed into my constructed div.
The order of events is as followed:
Bookmark Clicked -> Creates a modal popup div on the page being viewed -> runs an ajax call to my server, passing a unique ID of the user to retrieve some data -> then populates the dynamic content with this retrieved data.
Apparently on some site the ajax request was never received back.
Can some sites block my bookmarklett from gathering data via ajax from my site?
Is it possible that the site messed up the request being sent to my server for a response?
If so, is there any work around? Or do i need to ditch it all together.
This is how my ajax request works, and I have not seen it fail, but apparently it has.. It may have been an error on the users part (may have touched some of the code supplying the data to send with the GET request, I'm not sure though)
jquery.ajax({
type:"GET",
url:"mysite.com/api/getStuff",
data:"format=jsonp&userid=1234",
success:function(data){
// do stuff with the retrieved data
},
error:function(err, msg){
// response was not received
}
});
XMLHTTPRequest is subject to the same origin policy which is imposed by most browsers. For security reasons, it restricts XHR to the same protocol, domain, and port as the original page request.
Visiting the link I provided will also start you on your way to finding workarounds for this if it's something you want to do.
Crossdomain ajax requests are restricted. Use 'jsonp' or 'script' dataType.
Note that "Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation". More info is available on official jquery documentation
I know from experience that some mod_rewrite rulz messed up my ajax requests, i think you might have some problems with using ajax + mod_rewrite.