JSONP responseText on http error - javascript

I am using a jsonp ajax request with jQuery to send some data. When this data could not be processed for some reason, I would like to return the result with a http status other than 200. This way I can use my access logs to parse them for statistics.
Unfortunately, I don't get any response when the status code is not 200, although the jQuery callback is in the response body (when I check with firebug). Is there a way to catch the response?
$.ajax({
type: 'GET',
url: '{{ sendMsgUrl }}',
async: false,
data: { 'form': formData },
dataType: 'jsonp',
success: function(json2) {
if (json2.status == 'ok')
// do stuff
else {
// output error
};
},
error: function(xhr, status, error) {
// this doesn't work: it never gets here
alert(xhr.responseText);
var json2 = eval("("+xhr.responseText+")");
}
}).fail(function(jqXhr) {
// never gets here either
alert('status '+jqXhr.responseJSON);
});

No. JSONP doesn't use XHR. It injects a <script> element into the page.
In theory, you might be able to find an error event handler to that script, but it won't fire for cross-origin requests (and there isn't much point in using JSONP unless you are making a cross-origin request).
You'll never get any details of the HTTP response headers in any event handler when using JSONP.

Related

How should I fail gracefully when ERR_BLOCKED_BY_CLIENT? [duplicate]

I'm making an ajax jsonp request, but the failure error handling wont work. If the request is 404 or 500 it won't handle the error.
I've been looking around to find an answer to this, but can't find anything. There seems to be a solution with http://code.google.com/p/jquery-jsonp/, but I can't find any examples on how to use it.
function authenticate(user, pass) {
$.ajax ({
type: "POST",
url: "url",
dataType: 'jsonp',
async: false,
//json object to sent to the authentication url
data: {"u": userid, "p": pass},
success: function (data) {
//successful authentication here
console.log(data);
},
error: function(XHR, textStatus, errorThrown) {
alert("error: " + textStatus);
alert("error: " + errorThrown);
}
})
}
If you check jQuery.ajax() documentation, you can find:
error
A function to be called if the request fails (...) Note: This handler is not called for cross-domain script and cross-domain JSONP requests. This is an Ajax Event.
Because of that, you're forced to find workaround. You can specify timeout to trigger an error callback. It means that within specified time frame the request should be successfully completed. Otherwise, assume it has failed:
$.ajax({
...
timeout: 5000, // a lot of time for the request to be successfully completed
...
error: function(x, t, m) {
if(t==="timeout") {
// something went wrong (handle it)
}
}
});
Other issues in your code...
While JSONP (look here and here) can be used to overcome origin policy restriction, you can't POST using JSONP (see CORS instead) because it just doesn't work that way - it creates a element to fetch data, which has to be done via GET request. JSONP solution doesn't use XmlHttpRequest object, so it is not an AJAX request in the standard way of understanding, but the content is still accessed dynamically - no difference for the end user.
$.ajax({
url: url,
type: "GET"
dataType: "jsonp",
...
Second, you provide data incorrectly. You're pushing javascript object (created using object literals) onto the wire instead of its serialized JSON representation. Create JSON string (not manually, use e.g. JSON.stringify converter):
$.ajax({
...
data: JSON.stringify({u: userid, p: pass}),
...
Last issue, you've set async to false, while documentation says:
Cross-domain requests and dataType: "jsonp" requests do not support
synchronous operation.
Two ways to handle error,
There is no error handling for cross domain JSONP requests. Use jsonp plug-in available on Github https://github.com/jaubourg/jquery-jsonp that provides support for error handling.
jQuery ajax Timeout - Timeout after a reasonable amount of time to fire the error callback because it might have failed silently. You may not know what the actual error (or error status) was but at least you get to handle the error
I've been struggling like you for a while trying to handle errors on ajax jsonp DataType requests, however I want to share you my code, hope it helps. A basic thing is to include a timeout on the ajax request, otherwise it'll never enter the error: function
$.ajax({
url: "google.com/api/doesnotexists",
dataType: "jsonp",
timeout: 5000,
success: function (parsed_json) {
console.log(parsed_json);
},
error: function (parsedjson, textStatus, errorThrown) {
console.log("parsedJson: " + JSON.stringify(parsedjson));
$('body').append(
"parsedJson status: " + parsedjson.status + '</br>' +
"errorStatus: " + textStatus + '</br>' +
"errorThrown: " + errorThrown);
}
});
jsfiddle - Handle Errors with jquery ajax call and JSONP dataType - Error 404
I'm building a fragile JS project that uses jquery-jsonp, and came up with a dual-jsonp/ajax approach that handles errors no matter which method ends up being used.
function authenticate(user, pass) {
var ajax = ($.jsonp || $.ajax)({
'url': /* your auth url */,
'data': { /* user, pass, ... */ },
'contentType': "application/javascript",
'dataType': 'jsonp',
'callbackParameter': 'callback' // $.jsonp only; $.ajax uses 'jsonpCallback'
});
ajax.done(function (data) {
// your success events
});
ajax.fail(function (jqXHR, textStatus, errorThrown) {
// $.jsonp calls this func as function (jqXHR, textStatus)
// and $.ajax calls this func with the given signature
console.error('AJAX / JSONP ' + textStatus + ': ' +
(errorThrown || jqXHR.url));
});
}
Since both jquery-jsonp and $.ajax support the jQuery Deferred specification, we can merge the two error handlers together, handling 400 and 500-series errors, as well as lookup timeouts.
Old question but I had the same problem. Here is a solution that worked for me.
If you own the domain you shoot your request at, you can set a variable in the response and check for it on the client side.
Server Side:
SERVER_RESPONSE=true; Callback(parameter1, parameter2);
Client Side:
if(typeof SERVER_RESPONSE === 'undefined'){
console.log('No Response, maybe server is down');
}
else{
console.log('Got a server response');
}

jQuery.Ajax Error result

Im using MVC on server side and calling a function via jQuery.Ajax sending json type.
the function results with exception.
i want to invoke/trigger the error result function of the Ajax, what should i send back with the return JSON function?
for the example, let's say the return JSON is triggered from the catch section.
MVC Function
public JsonResult Func()
{
try
{
var a = 0;
return Json(a, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
FxException.CatchAndDump(ex);
return Json(" ", JsonRequestBehavior.AllowGet);
}
}
JavasScript call
$.ajax({
url: '../Func',
type: 'GET',
traditional: true,
contentType: "application/json; charset=utf-8",
dataType: 'json',
success: function (data) {
alert('s');
},
error: function (data) {
alert('e');
}
});
Quoting from this answer:
The error callback will be executed when the response from the server is not going to be what you were expecting. So for example in this situations it:
HTTP 404/500 or any other HTTP error message has been received
data of incorrect type was received (i.e. you have expected JSON, you have received something else).
The error callback will be executed when the response from the server is not going to be what you were expecting. So for example in this situations it:
HTTP 404/500 or any other HTTP error message has been received
data of incorrect type was received (i.e. you have expected JSON, you have received something else).
In your situation the data is correct (it's a JSON message). If you want to manually trigger the error callback based on the value of the received data you can do so quite simple. Just change the anonymous callback for error to named function.
function handleError(xhr, status, error){
//Handle failure here
}
$.ajax({
url: url,
type: 'GET',
async: true,
dataType: 'json',
data: data,
success: function(data) {
if (whatever) {
handleError(xhr, status, ''); // manually trigger callback
}
//Handle server response here
},
error: handleError
});
error callback is invoked when HTTP response code is not 200 (success) as well as when response content is not comply to expected contentType which is json in your case.
So you have to either send HTTP header with some failure response code (e.g. 404) or output non-json response content. In the latter case you can simply output empty string:
return "";
If you want to trigger an error in AJAX, but still know "why" it was triggered so you can customize the error message, see this post:
https://stackoverflow.com/a/55201895/3622569

Function didn't trigger?

I have this ajax call in my js. With this request I want to know if there is a previous opened session, in that case it will show the login form.
So, if there is no previous session, the server returns error 400 bad request (laravel response class). But when the server returns, the $.ajax object does not trigger the error function. Anyone knows why?
Server response
$data =[
'error' => [
'message' => 'Authentication Error',
'statusCode' => 400
]
]
Response::json($data, 400, [])
->setCallback(Input::get('callback'));
Ajax request
$.ajax({
global: true,
method: 'POST',
dataType: 'jsonp',
url: 'http://localhost:8082/api/checkAuth?callback=?',
success: function(response) {
return console.log(response);
},
error: function(a, b, c) {
console.log(a);
console.log(b);
return console.log(c);
}
});
I tried too getting the status code to trigger a function, but it does not work anyway:
** Ajax Request **
$.ajax({
global: true,
method: 'POST',
dataType: 'jsonp',
url: 'http://localhost:8082/api/checkAuth?callback=?',
success: function(response) {
return console.log(response);
},
statusCode:{
400: function(a,b,c){
console.log(a);
console.log(b);
console.log(c);
}
}
});
Thank you guys, for the help
SOME UPDATES:
Thanks to manish, I discovered this plugin for handling jsonp request, that triggers the error function. Does anyone know a way to capture the returned status code in the error function?
I assume that the server is returning 400 because it expects a POST request, jsonp is only capable of sending GET requests. Instead of using jsonp, you might want to use CORS.
There is no problem in your code, it is how json and jsonp responses are handled. Check this answer to get idea how to handle error response. You can use this plugin
to handle jsonp request-responses

using $ajax to perform GET request from tomcat server always fail jQuery

I have backend webService on tomcat server.always when I perform any request (post, get),code enters on error method.
jQuery code is:
var jqxhr = $.ajax(
{
type:"GET",
url:url
success: function() {
alert("success");
},
error: function() {
alert("fail");
}
});
my url is:
http://"192.168.20.220":6060/NostServices/rest/user/resend_activation_email/mailex#blah.com
error message on log is:
XMLHttpRequest cannot load http://"192.168.20.220":8080/NostServices/rest/user/resend_activation_email/dsgg#sdfkmj.com.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://"192.168.20.220":8383' is therefore not allowed access.
web service server is tomcat.
response of this requset can be 1 for success and -1 for mail not valid
and always enter on fail method and when I try to alert response it output [object object]
thanks you for your help
It's a JSONP request so your server side script needs to return data wrapped in callback:
For example
var url = 'http://example.com/req.json?callback=?';
$.ajax({
type: 'GET',
url: url,
async: false,
jsonpCallback: 'jsonCallback',
contentType: "application/json",
dataType: 'jsonp',
success: function(json) {
console.log(json);
},
error: function(e) {
console.log(e.message);
}
});
And on server side:
jsonCallback({});
As your error says your code is failing because of the cross domain error problem. A very detailed answer is found here:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '...' is therefore not allowed access
Please put in some effort to google these issues, this is a very common thing your trying and all errors have been encountered before and have been resolved somewhere. People will get very annoyed here if you show no effort to debug it yourself or provide all the required detail such as:
All relevant code
Print out of any variables in the code e.g. URL's
Any error message
A list of things you have tried
On a side note a URL should not have quotes it it. It should not be
http://"192.168.1.1":.........
it should be:
http://192.168.1.1:........

Cross-domain AJAX call returning string JSON, instead of JSON object

I am making a cross-domain AJAX call, and I am not sure if I am doing something wrong or the providers of the API call is incorrectly returning the JSON. Whenever I get the response from the API call, it is a string instead of a JSON object. Here is my AJAX call.
$.ajax({
async: false,
dataType: 'jsonp',
url: 'http://cross-domain/getSummaryStat.action',
data: { minDailyDate: start_param, maxDailyDate: end_param },
success: function(response) {
map = {
gamefuse: response["ROM-GF-Live"],
facebook: response["ROM-FB-Live"],
kongregate: response["ROM-Kongregate-Live"],
yahoo: response["ROM-Yahoo-Live"]
}
},
error: function(xhr, textStatus, errorThrown){
alert('request failed');
}
});
When the response comes back, here is response.result
"[{"dayRetention1":"0.01453800063053","visit":"601","installs":"203"},{"dayRetention1":"0.122484891199019","visit":"33863","installs":"10949"]"
NOTE: I set dataType to jsonp because it is a cross-domain AJAX call, and I was getting an error without it.
First, It looks like the returned string isn't even in correct JSON form. It's missing a close bracket at the end.
If this doesn't fix it then the issue here is probably on the server side. Since JSONP is JSON with padding, your return function shouldn't be:
function_name("the string that I return");
Instead you should have:
function_name({
"name":"Bob Loblaw",
"age":40
});

Categories