Synchronous cross domain jquery call, timeout defect? - javascript

on the internet i found this little piece of jquery magic, which does a synchronous cross domain json call.
For testing The called URL (http://localhost:8080/runsforever) does not return, it runs forever. (endless loop)
I have added the timeout property, but it doesn't work, it blocks for ever.
How to get timeout to work?
var jsonObjectInstance = $.parseJSON($.ajax({
url : "http://localhost:8080/inbound-servletapi/getRecommendations",
timeout: 5 ,
async : false,
dataType : 'json'
}).responseText);

Related

How can i stop hanging page when a request is send via Ajax

I am facing a serious issue... Whenever i use Ajax to send a request and get an response my browser got hanged.. and show no loading etc...
But when i response is retrieved from the Ajax then browser and page again start working...
Below is the code that i used.....
function ShowContestStatus(contestID)
{
$("#showContestDetails").html('<div class="loadercontest"><img src="assets/images/loading.gif">Loading Contest....</div>');
$("#RadioGroup1_0, #RadioGroup1_1, #RadioGroup1_2").prop('disabled', true);
$.ajax({
url:"process/processMyContest.php",
type:'POST',
cache:false,
async:false,
data : {act : 'showcontest', cid : contestID },
success:function(result)
{
$("#showContestDetails").html(result);
$("#RadioGroup1_0, #RadioGroup1_1, #RadioGroup1_2").prop('disabled', false);
}
});
}
Please help me on this... i want to get the same response as on other websites when you send a request and they are using ajax the page neither hanged and also each processing like scrolling etc is visible ......
So please suggest me good ideas.... so i can get rid of it and make my ajax smooth for page without effecting and irritate the other person by hanged...
Thanks in advance...:)
The problem is async:false... Since your ajax request is synchronous the script execution will wait for the request to complete to continue..
Since browser uses a single threaded execution pattern(either it will execute script or repaint or wait for user events at a time- not all at the same time), your browser tab will stop listening to user(so it will look like it is hanged)
function ShowContestStatus(contestID) {
$("#showContestDetails").html('<div class="loadercontest"><img src="assets/images/loading.gif">Loading Contest....</div>');
$("#RadioGroup1_0, #RadioGroup1_1, #RadioGroup1_2").prop('disabled', true);
$.ajax({
url: "process/processMyContest.php",
type: 'POST',
cache: false,
//remove async: false,
data: {
act: 'showcontest',
cid: contestID
},
success: function (result) {
$("#showContestDetails").html(result);
$("#RadioGroup1_0, #RadioGroup1_1, #RadioGroup1_2").prop('disabled', false);
}
});
}
Ajax.async
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 with jqXHR
($.Deferred) is deprecated; you must use the success/error/complete
callback options instead of the corresponding methods of the jqXHR
object such as jqXHR.done() or the deprecated jqXHR.success().
Make async:true for making the browser listen other events while running the ajax code.

How to set maximum execution time for ajax post with jQuery?

Is there a way to specify maximum execution time of an ajax post to the server so if the server doesn't respond, then keep trying for 10 seconds and then continue with the rest of the code??
Function doajaxPost(){
var returned_value="";
// #############I NEED THIS CODE TO TRY TO POST THE DATA TO THE SERVER AND KEEP
// #############TRYING FOR 10 SECONDS AND THEN CONTINUE WITH THE REST OF THE CODE.
jQuery.ajax({
url: 'ajaxhandler.php',
success: function (result) {
returned_value=result;
},
async: false
});
// ###################################################
alert(returned_value);
some other code
.
.
.
}
Use timeout:
jQuery.ajax({
url: 'ajaxhandler.php',
success: function (result) {
returned_value=result;
},
timeout: 10000,
async: false
});
However, alert(returned_value); will execute just after your call (won't wait for the call to finish).
The JQuery API documentation tells how to set a "timeout".
http://api.jquery.com/jQuery.ajax/
While other answers here are correct, learning to check the documentation for yourself is more valuable than knowing just this answer.
You can set timeout value for your ajax request.
timeout
Set a timeout (in milliseconds) for the request. This will override
any global timeout set with $.ajaxSetup(). The timeout period starts
at the point the $.ajax call is made; if several other requests are in
progress and the browser has no connections available, it is possible
for a request to time out before it can be sent. In jQuery 1.4.x and
below, the XMLHttpRequest object will be in an invalid state if the
request times out; accessing any object members may throw an
exception. In Firefox 3.0+ only, script and JSONP requests cannot be
cancelled by a timeout; the script will run even if it arrives after
the timeout period.
Here is an example:
$.ajax({
url: "ajaxhandler.php",
...
timeout: 10000,
...
});
Set a timeout (in milliseconds) for the request. This will override any global timeout set with $.ajaxSetup(). The timeout period starts at the point the $.ajax call is made; if several other requests are in progress and the browser has no connections available, it is possible for a request to time out before it can be sent. In jQuery 1.4.x and below, the XMLHttpRequest object will be in an invalid state if the request times out; accessing any object members may throw an exception. In Firefox 3.0+ only, script and JSONP requests cannot be cancelled by a timeout; the script will run even if it arrives after the timeout period.
Hopefully, this will help others like me who aren't completely fluent in JavaScript or, more to the point, aren't completely fluent in reading jQuery documentation.
I admit, I looked at the jQuery.Ajax docs, and easily enough found the section that talks about setting a timeout:
timeout
Type: Number
Set a timeout (in milliseconds) for the request. A value of 0 means there will be no timeout. This will override any global timeout set with $.ajaxSetup(). The timeout period starts at the point the $.ajax call is made; if several other requests are in progress and the browser has no connections available, it is possible for a request to time out before it can be sent. In jQuery 1.4.x and below, the XMLHttpRequest object will be in an invalid state if the request times out; accessing any object members may throw an exception. In Firefox 3.0+ only, script and JSONP requests cannot be cancelled by a timeout; the script will run even if it arrives after the timeout period.
But lacking an example, I was still clueless how to specify the timeout value. The secret sauce is at the top of the article, where it says:
In JavaScript, this translates to this sort of syntax:
$.ajax({
url: "https://example.com/my-endpoint",
...
timeout: 0,
...
});
In the above example (which specifies a timeout of 0 to disable timeouts for this request), each key/value pair (as mentioned in the documentation) appears in the code as [key]: [value]

Javascript Synchronization with JSON Requests

How can I make sure that a piece of code has executed completely before executing another? I am sending some ajax requests to a server and then using the returned data to generate the rest of the webpage. the things is, is that i need to have all that data in the webpage to proceed with the rest of the code as that code will affect what has been generated and, that code, runs before the json requests and all of that have finished... is there any way I can make sure this does not happen? I managed to solve it by performing the requests and then asking the user to press a button but that is a total no-sense way of doing it.
Any ideas?
Here is some code: The problem is that the second line is executed before the first (there are many calls to similar JSON functions).
$.getJSON(url, function(data){ $("#mycontent").append("..... stuff here...... create loads of dibs with class set to mydivclass"); });
...
$("div.mydivclass").hide();
Unforunately I cannot use the ajax synchronous property because: "dataType: "jsonp" requests do not support synchronous operations"
If you are using jQuery 1.5+ you can make use of deferreds to solve your issue:
function first_ajax_request() {
return jQuery.ajax(
// Your settings here
success: success_function_1
);
}
function second_ajax_request() {
return jQuery.ajax(
// Your settings here
success: success_function_2
);
}
function final_sucess_callback() {
// Do all your display work.
}
jQuery.when(first_ajax_request(),
second_ajax_request()).then(final_success_callback);
There is an excellent article on the topic that you should read up on as well by Eric Hynds. He gives some examples of exactly the kind of problem you are trying to solve.
jquery requests are asynchonize by default , so your code does not wait for the response , so you have no guarantee that code after request will execute after the response , so you can set the request synchronize by set the async property false , now the request is synchronize and you can gurantee the rest of the code will execute after the response from the server ,
like this .
$.ajax({
url: "page.php",
processData: false,
data: xmlDocument,,
async:false,
success: handleResponse
});

How can I do a synchronous request with jQuery?

Why don't return that function the responseText?
function LoadBookmarksAsXml()
{
return $.ajax(
{
type: 'GET',
async: false,
url: 'http://www.google.com/bookmarks/?output=xml&num=10000'
}).responseText;
}
(It works if I define a success-callback-function and set async to true!)
Thanks in advance!!
Edit: Don't worry about the cross-domain call; user603003 says (in a comment on a now-deleted answer) that this is in a Chrome extension where cross-domain requests are allowed.
The solution if someone wants to do the same:
return $.ajax(
{
type: 'GET',
async: false,
url: 'http://www.google.com/bookmarks/?output=xml&num=10000',
});
(You will get a XMLHTTPRequest object.)
I'm not immediately seeing why it's not returning it, but I'd still use a success callback:
function LoadBookmarksAsXml()
{
var result;
$.ajax(
{
type: 'GET',
async: false,
url: 'http://www.google.com/bookmarks/?output=xml&num=10000',
success: function(data) {
result = data;
}
});
return result;
}
Even though $.ajax returns an XMLHttpRequest object (in 1.4 or earlier) or a jqXHR object (in 1.5+), I'd still prefer using a success function and an error function for clarity. Also, different versions of jQuery give you different values for responseText on error (at least on Chrome; 1.4.4 returns an empty string, 1.5.0 returns undefined).
If there's any way you can avoid it, avoid it. Synchronous requests completely lock up the UI of most browsers (not just your page's UI, every page in every tab that browser is managing). Since ajax requests can take a second or two (or five, or ten), this makes for a very unpleasant user experience. Nearly all the time, you can avoid it by refactoring your function so it accepts a callback to use to supply the result:
function LoadBookmarksAsXml(callback)
{
$.ajax(
{
type: 'GET',
url: 'http://www.google.com/bookmarks/?output=xml&num=10000',
success: function(data) {
callback(data);
},
error: function() {
callback(null);
}
});
}
Off-topic: I'll be surprised if the request works at all, though, because on the face of it (unless you work for Google), that request will fail because of the Same Origin Policy. Various ways to get around the SOP:
JSONP
CORS (but it requires browser support and that www.google.com allow the request from your origin)
Using YQL as a proxy
$.ajax never returns the response text, it always returns the XMLHTTPRequest object created to make the Ajax call.
You'll still need to define a success callback I think, e.g. one setting a local variable which you can then return.
Standard disclaimer: Synchronous requests are a usually discouraged practice because they can freeze the current page.
Waiting for the response of a function is not asyncronous, the ajax call will have a response when it is done, you have to take care of the response then, by defining callbacks for the successful event.
You have ti break up your code to at least two parts. First part is before the ajax call, second part is after the success, and put everything you want to do with the requested data in the success callback. Asyncronous requests work this way.
Doing that is a really bad idea. Javascript will block for the duration of the HTTP request, which is to say nothing else in the UI thread will run until the ajax call returns. Use a callback.
By design, asynchronous requests can't deliver a responseText out of the blue ;-)
You HAVE to set a callback function and decide how you will handle the responseText.

JavaScript for loop is making the UI unresponsive

I'm making a mailing list script that takes advantage of ajax (async=false) to send emails in chunks.
Basically the cycle is this:
var i = 0;
for(i;i<num_rows;i=i+mxt){
if($("#panic").val()=='1'){
break;
}
perc = (i*100)/num_rows;
startThread(i,perc);
}
Tha panic value is set by a button, the problem is that during the cycle (that works) I can't interact with the page.
What am I doing wrong?
Thank you
EDIT:
function startThread(i,perc){
l_a = i;
l_b = mxt;
headers = '&mail_from='+mail_from+'&mail_from_name='+mail_from_name+'&mail_subject='+mail_subject;
$.ajax({
type: "POST", url: "ajax/thread.php", data: "l_a="+l_a+"&l_b="+l_b+headers,
success: function(html){ $("#progressbar").progressbar({value: perc}); },
async: false
});
}
Your startThread() function name is misleading, because JavaScript in web browsers in not only single threaded, but it shares the same thread with the page rendering.
Since you're using async=false, the $.ajax call become a blocking function, and this blocks the page rendering thread, making the UI unresponsive.
Quoting the jQuery documentation (emphasis added):
async
Default: true
By default, all requests are sent asynchronous (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.
Possible solutions:
Piggyback your data in one JSON object, and send just one $.ajax request. If possible use async=true.

Categories