Having a script provide a boolean 'answer' to jQuery's .load() method - php

A quick question of perhaps a more speculative nature. I've been getting heavy into jquery lately to handle all the ajax in my web apps.
Right now I'm building a bidding system in PHP that makes heavy use of mod_rewrite. I'm using jQuery with a confirm dialog to send an Ajax request that will spend some of the user's predeposited credits on a bid. The ajax request to spend is sent with the cost as a post parameter to a PHP controller that spends the users credits and then echos the output, which jQuery then places back into the document.
It's working fine, but what I'm wondering is if there is a better way to make jQuery handle the refusal of the purchase if the user has insufficient credits. Right now I have the php answering with an echo that displays this message with a link to the make a deposit page... but I'd rather have a redirect happen automatically.
Is there some way my jQuery script could be notified with the boolean of success or failure before .load finishes, and then redirect in the case of failure? Possibly through HTTP headers determining the handling? The only way I could think of is to place a true or false in an html element that gets check in the callback after .load() and in the case of a false perform a redirect.
Thanks and sorry for the explanation length.

If every bidding attempt requires going somewhere else, why use AJAX in the first place?
Anyway, if you look at jQuery's API documentation you'll see that load() is not the only function available. Most of the are simplified versions of ajax(); if you use this one, you can control all possible events right from there. No need to mess with HTTP headers!
I suggest you redesign your server-side script so it returns a JSON object. Then, you can send back all the different types of responses:
{
biddingSuccessful: true,
linkToDepositPage: "http://example.com",
textToDisplay: "Your bidding was successful"
}

Use the lower level $.ajax call to have full maximum control over the request. Ideally, instead of sending a success 2xx response, send an error response which will automatically get sent to your error callback.
$.ajax({
url: '..',
success: function() {
// if it gets here, then assume credits were used
},
error: function() {
// some error happened
// if error was about insufficient funds, then redirect
}
});
From the server, send the success response as you are doing right now. However for errors, change the response header, and send a JSON object or plain text indicating what the error was. And there is a header for exactly what you are looking for. It's 402 - Payment Required :)
header('HTTP/1.1 402 Payment Required');
send a JSON object as response with more details:
{
status: 'error',
reason: 'Insufficient Funds',
balance: '$2.78',
amountRequested: '$3.50'
}
For the updated comment, you need to use a closure (better than global variables :)
Suppose the outer function gets the element name/ID, wraps that value through a closure in the success callback. Please let me know if this is not what you intended.
function makeAJAXCall(elementName) {
$.ajax({
success: function(...) {
// elementName is available here through a closure
alert(elementName);
}
});
}

if the callback function is like "function (data) {" then you could return "NSF" or something like that, and simply compare 'data' to 'NSF', and do the redirection with window.location

Related

success and failure criteria for ajax(jquery post) purposes

I have been looking around the web (obviously in wrong places) to find what is the success and failure criteria for ajax(jquery post) purposes.
For example, let's say I am using ajax to post to a php script. The script can return:
exit 0
exit 1
jason array
return
etc...
When would those return values be translated into success and when into failure?
As you may already know $.ajax() supports beforeSend, success, error and complete callbacks.
So what should my script send in case of success and in case of failure for the appropriate callback to be triggered.
Ben is right, but I'll expand a little.
jQuery determines success or failure based on the HTTP response code of the page being called. Note that this is not the same as the content in the response that is sent back.
As an example, let's say that you have your PHP script located at http://url.com/script.php
When a user hits that site, they are going to get a response from the server. That response could be a JSON object, it could be an HTML page, or it could be an empty response. In all of these cases, the response code would likely be 200. A 200 response code means that the server understood the request, accepted it, and sent something back.
Now let's say that a user tries to hit http://url.com/notascript.php
The server doesn't know what to do with that (assuming that notascript.php doesn't actually exist). It fails the request, and sends back a response -- probably with the response code 404 (or something else in the 4xx range).
So if you know the actual URL, then how does jQuery's error handler ever get called?
Well, let's say that your AJAX call is trying to load a blog post, and tries to make a call like this: http://url.com/post?id=5. If your PHP script determines that there is no blog entry with an ID of 5, then you probably shouldn't send back a successful response. Rather, a 4xx response would be more appropriate. And PHP has a built-in function for that:
<?php
http_response_code(404);
?>
Now, the response will be read by jQuery as a failure, and the error handler will be called.
Further reading:
http_response_code() function
RFC2616, which defines HTTP response codes
REST
I believe it's based on header codes (ie, 200 - success). You can send your own special errors back though e.g. How to receive error in jQuery AJAX response?
You shouldn't make Ajax error if you have a problem with the code in the page being requested. As far as Ajax is concerned, so long as the page physically is successfully requested, it has performed properly. Any errors within the page being requested are not a fault of Ajax, so should be handled by your code after a successful load of that page. Using custom headers as in the link above will make it easier for you to do that.
Ajax requests page --> Page loads & no errors --> page request successful --> You Perform result error checking
vs
Ajax requests page --> Page loads & has errors --> page request successful --> You Perform result error checking
As you can see, it doesn't matter if the page being requested has errors, it's not an Ajax fault, so shouldn't be treated as one.
You can select one pattern that always printed for success, other cases like ajax failure can be known via AJAX itself (HTTP response code): for example:
You always print: yes for success and if correct result found
You always print: no for success and if incorrect result found
If none of above returned then its ajax failure or if the script prints another word then you need to check your PHP.

how can catch event ajax send to server, not waiting for server respond

My problem is that when user click on link on website, i using jquery to catch event click and ajax to update database
if i do something like this, it will take a litle time because of the waitting for respond form server
$.ajax({
success: function() {
...
window.href = link;
}
});
I want something like
$.ajax({
alreadysend: function() {
...
}
});
I read document ajax, but i can't find any solution for my problem.
EDIT: i solve my problem, i need to work hard on jQuery, thanks you all
It does that by default since Ajax is asynchronous! If you want code to execute regardless if the server was reached and responded, simply put your executing code after the Ajax block.
On the flip side, if you want to tell if the user already made the submit action, you can use a application-scope variable to toggle on call and completed events. (I.e set to true when the user initiates a Ajax call. On completion, set to false. Disallow the call I already true)
Simply call your code just after the call to $.ajax:
$.ajax({success: function(){
// done after server response
}});
// do something immediately after
Ajax call is asynchronous, so your script is not blocked.
Why don't you just call the function you want to call after the $.ajax line? Like this:
$.ajax({ ... });
do_things();
Edit If you want to do a redirect, you'll have to wait for the AJAX call to come back to be sure it was successful or not. If you don't care whether it was successful, and just care about it making the call at all, you can place it in the line after the $.ajax call, since the call happens asynchronously. In any case, we need some more information on what you want to achieve exactly.
I am not 100% sure of what you are trying to do, but if you want to wait for the ajax call to return before your code carries on you can set it to do so by setting async to false, although its worth noting that this is kind of counter productive and is deprecated in jQuery 1.8.
http://api.jquery.com/jQuery.ajax/
By default, all requests are sent asynchronously (i.e. this is set to
true by default). If you need synchronous requests, set this option to
false. Cross-domain requests and dataType: "jsonp" requests do not
support synchronous operation. Note that synchronous requests may
temporarily lock the browser, disabling any actions while the request
is active. As of jQuery 1.8, the use of async: false is deprecated.

Sequential AJAX Requests

I have a situation where I need to make sequential AJAX requests represented by an ordered list (<ol><li>..) on the page. I use jQuery.
Requirements:
Each request has to wait for the previous one to complete with a successful status.
The success or error message needs to be appended to the corresponding list item.
The process should halt if an error occurs on any item.
Errors may be HTTP errors or an error returned with the JSON formatted response.
What I have working:
Looping over list
Making $.getJSON call to the desired URL for each list item
The 'Requirements' items are the pieces I haven't worked out.
SOLUTION
I ended up using jQuery Message Queuing, but I didn't find a way to return HTTP errors to the item that spawned the request. I instead display an error in a different place.
$(document).ajaxError(function(event, response, settings, exception){
$('#Admin').append('<p class="error">' + response.status + ' error requesting page:<br />' + settings.url + '<br />Reload this page to continue.</p>');
});
I would prefer to display HTTP errors with the item if anyone can help me with that.
jQuery Message Queuing is what you might be looking for. It performs serial (sequential) AJAX requests.
You can view a demo here.
There can be possibly two ways:-
Use of jQuery.ajaxQueue Plugin. This plugin will help you manage the "Ajax race conditions".
Use of Synchronous call to jQuery.ajax (click the "options" tab to see them). To make the call synchronous, you'll set the "async" option in the Ajax call to false. But, it'll slow things down.
Hope it helps.

How to deal with session timeouts in AJAX requests

I'm sure you're all familiar with the voting systems that use AJAX (Um... look right over there <----)
I have something similar and when you vote up or down it uses AJAX to request the new value from votes.php. The problem is that I am using a session to get the userid so a person can only vote once. What happens if they sit on the page for an hour and then vote so the session is no longer there? What would be a good way of handling this situation? Should I redirect their page to the login screen? If so, how can I do that from the votes.php page that is being referenced by the AJAX request? Am I overlooking a good way of handling this situation? Any advice would be helpful.
Consider returning an http status of 401, and a JSON object detailing the reason. If you're using jQuery, that'll drop you to the error() callback, which you can then parse your object.
$.ajax({
data: {},
dataType: 'html',
success: function(data) {
// do whatever here
},
type: 'POST',
url: 'myserver.com',
error: function(XMLHttpRequest, textStatus, errorThrown) {
// XMLHttpRequest.responseText has your json string
// XMLHttpRequest.status has the 401 status code
if (XMLHttpRequest.status === 401) {
location.href = 'login.php';
}
}
});
I'm not familiar with PHP anymore, but this should work for just about any environment. You may have to suppress any automatic login form redirection though. In asp.net mvc the framework will see the 401 and push the default login form back, with a status of 200.
You should only store a link to the users identity in the session. Use sessions to identify a user as x and then get user x's information from the database.
If your problem is with users sessions timing out then you should reconsider how you're using your sessions. Perhaps make them last until the browser closes? If you really want to make them a duration, then perhaps ping the server in intervals to keep the session alive.
Decide in your php script whether or not the user should be able to vote. If the session isn't set, or if they have already voted, return a message that you can identify with on the client side. If they already voted perhaps return "voted":"true" in a JSON object. Use JS to parse this object and understand what it means, taking the appropriate action. If the session isn't set, perhaps return "session_set":"false", and then make javascript redirect with a window.location = "login.php" etc.
Only increment the counter for the user on a successful return of a counted vote.
This is an old thread, but I wanted to share my solution that is working really well.
In my framework the system redirects the user to the login form any time they try to access a page and the session has timed out or is not valid.
I added to the top of the login form the following html comment:
<!--LOGINFORM-->
I created a wrapper for jQuery's $.ajax function which checks for this string on every request, and if it is there it shows a dialog popup saying that their session has timed out.
You can use this by just calling:
ajax.get('http://someurl.com', function(data){
//Do stuff
});
Hope it helps someone.
var ajax = {
check_login : function(resp){
if (resp.substring(0, 16) === "<!--LOGINFORM-->"){
// Show a popup or redirect them to login page!
return true;
}
return false;
},
get : function(url, success){
if (typeof data =='undefined'){
data = null;
}
$.ajax({
url: url,
type : 'GET',
success : function(resp){
if (!ajax.check_login(resp)) {
success(resp);
}
},
});
}
};
You structure the Javascript code that makes the Ajax request to accept a special result (say, -1 where a >=0 number would normally be, such as, a count of votes) to mean "sorry bub, you're timed out" and redirect to the re-login page (which can take as an optional parameter a message explaining to the user they timed out, &c).
You could create a javascript function that could ping the server every 10 minutes via something like
setTimeout("Ping()", 60000);
If you want to navigate the user to the login page if they connect with a faulty session then I would first verify the session and if it fails send a
header("Location: ...");
http://ca2.php.net/manual/en/function.header.php
From a user perspective, the best solution is to pop up a message and login form, saying something like "You are not logged in or your session timed out". Digg does this very well.
As for the actual AJAX implementation, swilliams' 401 suggestion is solid. Alternatively, you can simply return a specific string on failure.

Complete AJAX feedback

I build JQuery/JS/PHP/mySQL app with DB records management and need to provide reliable & complete feedback to the user on AJAX calls, modifying back end DB records. The problem IMHO is $.ajax success: and error: functions indicate just AJAX transport layer success and not the whole process. What if DB modification fail? How can one provide the complete feedback to the user?
I ended up with
$.ajax({
url: "/action/delete",
data: "rowid="+rowid,
complete: function(xmlHttp) {
if ( xmlHttp.responseText ) alert('Success - back end returned "success"');
else alert('failure - back end returned NULL')
}
});
and PHP response:
$success = deleteRecord( $_GET(rowid) );
if($success) {
print 'success';
} else {
print NULL;
}
exit();
The idea is simple - if I manage to get positive feedback from the back end, then the whole operation succeeded, if not - user don't care where problem occurred.
Thank you in advance, your feedback is highly appreciated.
If you respond to the request with some json data instead of just some new html to insert into the DOM, you can place whatever kinds of error codes and messages you like with the data. For example, if your response was something like...
{
errorstate: 0,
errormsg: "All systems are go",
displaytext: "stuff I want to display when all goes well"
}
Your javascript code can examine this data and do whatever it feels it needs to. It also allows you to push more of the error handling into your server script which can often be simpler.
Try http://docs.jquery.com/Ajax/jQuery.getJSON#urldatacallback
One possible solution would be to use the HTTP response code to signal a failure, like 200 OK, everything's ok, and 500 Internal Server Error on error, which you can simply check when you reach state 4.
In PHP I believe this is done through header("HTTP/1.0 200 Ok") before any other data is sent. If you're afraid data will be sent by mistake before you can evaluate the correct header to set you can turn on output buffering.
How you wish to present the data is of course up to you, you could for example on 500 just have document.getElementById("myerrorbox").innerHTML = xmlHttp.responseText, or similar, and render a partial html-document in your php-program.
I send status messages back to the client. Along with the error flag. And then my JavaScript code displays the message it got from the server, and colours the message according to the error flag.
I find that to be quite efficient.

Categories