JQuery JSONP randomly generated callback function - javascript

I'm using JQuery to make JSONP requests and the documentation is quite confusing.
I have several questions:
A JSONP call is always async, is that correct? So the async:false would be simply ignored?
If the jsonpCallback parameter is specified, this function will be executed when the data are retrieved. But right after, also the success callback will be executed. Jquery advices NOT to specify the jsonpCallback function(only for caching?). What is the role of this function in relation with the success function?
If the jsonpCallback is not specified a random callback function will be created and attached to the window object. Something like jQuery1360574548776335413_1776656584447, what is its role? How does it work? Does it have any relation with the success function?
Is the error callback never called?
Here's my code:
(function($) {
var url = "https://www.googleapis.com/books/v1/volumes/zyTCAlFPjgYC";
$.ajax({
type: 'GET',
url: url,
// JSONP always async?
async: false,
jsonp: "callback",
jsonpCallback: 'jsonCallback',
contentType: "application/json",
dataType: 'jsonp',
success: function(json) {
console.dir(json);
},
// Error never called?
error: function(e) {
console.log(e.message);
}
});
})(jQuery);
function jsonCallback(json) {
$(".test").html(json.volumeInfo.title);
}

A JSONP call is always async, is that correct? So the async:false would be simply ignored?
That is correct
If the jsonpCallback parameter is specified, this function will be executed when the data are retrieved. But right after, also the success callback will be executed. Jquery advices NOT to specify the jsonpCallback function(only for caching?). What is the role of this function in relation with the success function?
The success function is your callback. Jquery generates a random function name usually. If, however, you're making several of the same requests and would instead like to allow the browser to cache calls, you can specify the function so that a randomly generated one is not created. Inspect the network requests and you'll see (as long as your server is set up to support it) that if you specify the name, you should get 304 - Not Modified (edit: on subsequent requests after the first), while other calls always return 200 OK
If the jsonpCallback is not specified a random callback function will be created and attached to the window object. Something like jQuery1360574548776335413_1776656584447, what is its role? How does it work? Does it have any relation with the success function?
Is the error callback never called?
That callback function should contain the code you put in success. The error event is fired if there is an error with the actual request, such as an invalid domain name, 401 server response, and etc.

Related

Jquery ajax response not calling Success method

I am pretty much new to ajax and working on jquery ajax request. Ajax callback is not calling success method. Interaction is between cross-site domains.
My AJAX request looks like
$.ajax({
timeout: 20000,
url: 'test.com',
crossDomain: true,
dataType: 'jsonp',
success: function (data) {
console.log('callback success');
this._cache = data;
localStorage.token = data.access_token;
} });
There are no errors in this call.
This ajax request is not calling success function.Request is returning json data. it's just success method is not getting called.
This ajax request is not calling success function.
Get request is getting fired successfully. I can even trace the response in fiddler with 200 http response.For some reason success method is not getting called.
it's returning json object, which I've traced in fiddler
You're telling jQuery to expect a JSONP response, so it is trying to execute the JSON document as if it were a JavaScript script (because that is what JSONP is). This fails because it is not JSONP.
Either return JSONP instead of JSON or (assuming the server returns the correct Content-Type) remove dataType: 'jsonp',.
ok... I came here with the same problem... and when I read that specifying datatype:jsonp never calls success as a callback per #mondjunge from a comment above, it started me thinking about some behavior I saw earlier from my code and that maybe datatype:json might have the same behavior for what ever reason here too.
So after reading this page I took out my datatype declaration from my ajax request and my servlet returned the proper data payload, returned a 200, and jquery called the success function finally and modified my DOM.
All those steps happened except the last one until I removed my datatype from my ajax call. NOT what I was expecting!
Hopefully someone else can shed some light on why this happens... for now at least the few that don't lose their minds to this issue that find this post can do this in the mean time.
Check if your ajax is executed
Check it's status. If response code is != 200, than you should add error method also, for error handling.
Try this:
$.ajax({
timeout: 20000,
url: 'test.com',
method: 'GET',
crossDomain: true,
dataType: 'jsonp',
success: function (data) {
console.log('callback success');
this._cache = data;
localStorage.token = data.access_token;
},
error: function(xhr, error){
console.debug(xhr); console.debug(error);
},
});

Is this a scope issue in JavaScript / JQuery? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it posible to use ajax respone outside of it?
I've created the following JavaScript routine that goes to a WCF oData service and gets some data. In the success element I get the results into the results variable and alert them - I see that there are objects returned. When I run the second alert, outside of the ajax call and before returning the results, the results variable is "undefined".
Can anyone please tell me where I'm going wrong?
function retrieveJsonpODataSet(baseUrl, query)
{
var oDataUrl = baseUrl + "?$format=json&$callback=?";
var results;
$.ajax(
{
url: oDataUrl,
contentType: 'application/json; charset=utf-8',
type: 'GET',
dataType: 'jsonp',
async: false,
success:
function (data, textStatus, xhr)
{
results = data.d;
alert(results); // This shows the results
},
error:
function (xhr, textStatus, errorThrown)
{
alert("Query failed.\n\n" + oDataUrl + "\n\n" + errorThrown);
results = null;
}
});
alert(results); // This shows "undefined"
return results;
}
Please ignore the query parameter - I've not finished the routine yet.
EDIT
Initially I had no async:false in the ajax call. I've added that now but it doesn't fix the problem.
The ajax call is an asynchronous operation. It fires and your code does not stop at it. So results is returned which at that point is undefined. What you need to do is to pass callback to the function.
function retrieveJsonpODataSet(baseUrl, query, callback) {
/* some code */
$.ajax({
/* some settings */
success: function(res) {
/* some code */
callback(results);
}
});
}
Now you use it like this
retrieveJsonpODataSet(baseUrl, query, function(res) {
/* Hurray, I have result now in res variable! */
});
DO NOT USE async: false OPTION! It blocks ALL scripts untill the call finishes... and what if it does not finish at all?? You will be blocked forever.
EDIT
I've missed that the request is JSONP. In that case async: false won't even work (it does not work for cross-domain requests and JSONP). So you have to use callbacks anyway.
A fellow Richard!
This isn't a scope issue, but more of an execution one. Both the success and error options are event handlers, and run asynchronously (hence it being called AJAX). This essentially means that the alert(results) and return results can, and likely will, get executed before the success or error events are triggered.
Your ajax is async, so the alert executes before the ajax completes. You need to set the ajax call async property to false in order for script to halt the execution until ajax request is made & processed.
However, jQuery docs says:
async
Default: true
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.
AJAX request are sent, without the script waiting for a response, that's what Dave Newton means by A-synchronus, put the alert inside the success callback function, and you'll see what the actual response is.
alternatively, you can specify the async property, and set it to false, to force your script to wait for the response, before continuing.

ajax calls to controllers. How to indicate success, complete, and error

If I make an ajax call to a controller.... what needs to happen in the controller so that the ajax call then calls
1) complete:
2) success:
3) error:
4) any other callbacks that exist.
For ex. I have this ajax call.
$.ajax({
url: "/ContactPartial/ContactUs",
type: "POST",
data: JSON.stringify(data),
dataType: 'json',
contentType: "application/json; charset=utf-8",
complete: function () { },
success: function () { },
error: function () { }
});
In other words, what can I do inside /ContactPartial/ContactUs to control which of the 3 (complete,success,error) gets called after the controller code executes.
Also, how is this related to related to return Json(new {some: data});
These three callbacks are related to the status of the Ajax call. These are called depending on success of the call. For complete details refer to the documentation
So, if the server responds with a success (200), then both the Success and the Complete handlers would be called. In the complete handler, you might put some code to dismiss a modal window (regardless of success or error), and in the success function, you might put code to let the user know the call was successful, reload a grid view, etc. Also, keep in mind that the callback functions don't have to be anonymous functions, they can be defined functions that are shared among several Ajax calls.
EDIT:
If you are wanting to force the server to generate an error, take a look at:
The HttpResponse class, specifically the StatusCode property
This SO post explains more too (generating a 401 error)

Jquery ajax onSuccess event

I am doing AJAX with JQuery but every time the "onSuccess" event must be executed after another AJAX request disconnected.
Here is the code:
d.ajax({
url: f.options.url.offline,
dataType: "jsonp",
jsonp: "callback",
cache: false,
data: {
status: "offline",
ticket: f.connection.options.ticket
},
success: function(g) {
f._offlineSuccess()
},
error: function() {
f._offlineError()
}
})
All my AJAX requests are JSONP, and when the above code is triggered, there is another AJAX connection (long polling request, last about 10 senconds) already established in the mean time. So the "f._offlineSuccess" function is always executed after another AJAX connection disconnected.
I can not see any relationship between the two AJAX requests, and I don't know why the "onSuccess" function must be executed after another AJAX connection stopped.
Any help is appreciated~
================================
updated:
I just found out if I have two JSONP connection at the same time, the "onSuccess/onFailure" function will be blocked. I don't know if some one encountered the same problem before?
Ajax requests are asynchronous. so a new request is not going for the previous one to finish. If you want that behaviour use async parameter to false, or use the complete() function to call for another request. This will fire only when the first request is finished.
UPDATE
For JsonP use jQuery.getJSON() and do the second request on callback if the call was succesfull.
function (data, textStatus) {
// data will be a jsonObj
// textStatus will be one of the following values:
// "timeout","error","notmodified","success","parsererror"
this; // the options for this ajax request
}
If you use firebug - net tab, you will be able to see the full url of the two jsonp requests. You should be able to see the callback function names on the end of the url. Are these different or the same? I can only assume they are the same.

using a named function as the callback for $.getJSON in jQuery to satisfy Facebook request signing demands

I'm trying to access the Facebook API Admin.getMetrics method via jQuery. I'm correctly composing the request url on the server side (in order to keep my app secret secret). I'm then sending the url over to the browser to be request using jQuery.getJSON().
Facebook requires that I send a copy of all of my request params hashed with my application secret along with the request in order to verify my authenticity. The problem is that jQuery wants to generate the name of the callback function itself in order to match the name it gives to the anonymous function you pass in to be called when the data returns. Therefore, the name of the function is not available until jQuery.getJSON() executes and Facebook considers my request to be inauthentic due to a mismatched signature (the signature I send along does not include the correct callback param because that was not generated until jQuery.getJSON() ran).
The only way I can think of out of this problem is to somehow specify the name of my function to jQuery.getJSON() instead of allowing it to remain anonymous. But I cannot find any option for doing so in the jQuery AP.
The only thing that did the work for me were the following settings
jQuery.ajax({
url: fbookUrl,
dataType: "jsonp",
type: "GET",
cache: true,
jsonp: false,
jsonpCallback: "MyFunctionName" //insert here your function name
});
The use of jQuery.getScript turned out to be close to -- but not quite -- the answer. Using getScript eliminates jQuery's need to add the dynamically named anonymous function to the request params (though it will still do that if you go ahead and pass it an anonymous function as in the above code). However, the default in jQuery.getScript, as in all the other calls in jQuery's Ajax library, is to append a further additional argument _=12344567 (where 1234567 is really a time stamp). jQuery does this to prevent the browser from caching the response. However, this additional breaks my signing of the request just like the auto-named callback function.
With some help on #jquery, I learned that the only way to get jQuery not to mess at all with your params is to make the request using the base jQuery.Ajax method with the following arguments:
jQuery.ajax({
url: fbookUrl,
dataType: "script",
type: "GET",
cache: true,
callback: null,
data: null
});
(where fbookUrl is the Facebook API url I'm trying to request with its full params including the signature and the callback=myFunction). The dataType: "script" arg specifies that the resulting JSONP should be stuffed into a script tag on the page for execution, cache: true tells jQuery to allow the browser to cache the response, i.e. to skip the addition of the time stamp parameter.
You can pass the JSONP option to $.ajaxSetup that will allow you to fix the function name that gets called, the docs read as follows:
jsonp String
Override the callback function name in a jsonp request. This value will be used instead of 'callback' in the 'callback=?' part of the query string in the url for a GET or the data for a POST. So {jsonp:'onJsonPLoad'} would result in 'onJsonPLoad=?' passed to the server.
See here http://docs.jquery.com/Ajax/jQuery.ajax#options for more details
This is a better solution with a fixed callback:
window.fixed_callback = function(data){
alert(data.title);
};
$(function() {
$.getScript("http://api.flickr.com/services/feeds/photos_public.gne?tags=cats&tagmode=any&format=json&jsoncallback=fixed_callback", function(data) {
alert('done'); } );
});
The problem with this callback is you can only handle one kind of request at a time as the function is globally registered. The callback function would probably have to turn into a dispatcher for the different kinds of data that it could retrieve and call the appropriate function.

Categories

Resources