Why won't jQuery call my Ajax error handler? - ajax

I have the following jQuery Ajax call (There are no other global settings/handlers):
$.ajax( {
url: "http://www.blah.com/url/does/not/exist",
type: "get",
data: someData,
dataType: "json",
error: function (xhr, msg, ex)
{
alert("Failed: " + msg);
},
complete: function (xhr, msg)
{
alert("Done: " + msg);
}
I would expect my error handler to be called, but instead the complete event fires and the alert displays Done: success. In my Javascript console, I see the following message:
XMLHttpRequest cannot load http://www.blah.com/url/does/not/exist.
Origin null is not allowed by Access-Control-Allow-Origin.
Why won't my error handler get called?
What is the meaning of the Origin message logged to the console?
Thanks!

Looks like the only way is to receive the server response in my success method and store it in a global variable, which I'll check in the handler for complete (which always gets called). No response means the request failed.
It's a shoddy way of handling errors in this otherwise excellent libary.

Your error handler isn't called because the AJAX request doesn't even take place: the browser refuses to do that because of the same origin policy: the data you're requesting would come from a different site than the one serving your page.
You can try using the JSONP data type to work around the problem:
$.ajax({
url: "http://www.blah.com/url/does/not/exist",
type: "get",
data: someData,
dataType: "jsonp",
error: function(xhr, msg, ex) {
alert("Failed: " + msg);
},
complete: function(xhr, msg) {
alert("Done: " + msg);
}
});

Related

Express res.jsonp returns two callback names to Safari Extension AJAX call

I'm building an extension in Safari, using Express.js on the back end. I make an AJAX call to the server, and the server responds with what appears to be a double callback name:
jQuery191026131771644577384_1364321159940 && jQuery191026131771644577384_1364321159940([
{
"foo": "bar"
}
]);
Here's the AJAX:
$.ajax({
type : "GET",
data : { 'something': 'something more'},
url : "http://localhost:3001/api/login/?callback=?",
dataType: 'jsonp',
success: function(data, text){
console.log(data)
},
error: function (request, status, error) {
console.log("ERROR: " + status + error );
}
});
...and here's the Express.js:
app.get('/api/login', function(req, res){
res.jsonp([{'foo':'bar'}]);
});
The browser is reporting a parse error, likely because of the double callback stamp above.
Clues?
It's not a double callback, it's the same as doing func && func(), it just makes sure that the function exists before calling it, so avoid throwing an exception.
Hector has it right in the comments: Try removing callback=? from the URL

Why is this basic json call not working?

The following JSON call always hits the AJAX error handler, and I can't figure out why:
$.ajax({
type: "GET",
url: '<%= Url.Action("MyTest", "Detail") %>',
dataType: "json",
error: function (xhr, status, error) {
alert(xhr + " | " + status + " | " + error);
},
success: function (json) {
alert(json);
}
});
All I get is Failed to load resource: the server responded with a status of 500 (Internal Server Error) http://localhost:4497/Detail/MyTest?_=1320681138394
When I set a breakpoint in the controller, I can see that it's being reached, so I'm not sure where the request is falling down. Here's the action in the DetailController:
Function MyTest() As JsonResult
Return Json("Hello")
End Function
Any ideas?
The jQuery error handler is fired because it failed to parse the returned page as valid JSON. Since you get 500 internal server error, the page most likely doesn't contain valid JSON.
Load this page in your browser and fix it until it gives valid json:
http://localhost:4497/Detail/MyTest
After it is giving valid json in the browser, try the jQuery ajax call.
I have no idea of even the basic functionality of VB.NET but can you make so that the only thing that is printed on http://localhost:4497/Detail/MyTest is like:
print( '{"message":"hello"}' );
If the only thing the page is outputting is {"message":"hello"} then json error handler will not fire

Returning Json from controller, never a success

I'm successfully posting to my controller with the following code, however, success is never being hit only error. What am I doing wrong?
JS:
$.ajax({
url: '/Home/Subscribe',
type: 'POST',
dataType: 'json',
data: { email: $('#sube').val() },
success: function (data) {
// get the result and do some magic with it
alert(data.foo);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
Controller:
[HttpPost]
public JsonResult Subscribe(string email)
{
return Json(new { foo = "bar", baz = "Blech" });
}
In IE, press F12 to open developer tools. Go to Network tab and click on Start Profiler. Send a request to your Subscribe action - in a list below you will see details of sent request and returned status code. Double click on request to see details - you can then see body of your response. If the request failed with a server error, you will see that error in a body of your response.
One wrong thing I see with your code is that you have hardcoded the url:
url: '/Home/Subscribe'
You should never do this. You should always use url helpers when generating urls in an ASP.NET MVC application:
url: '#Url.Action("Subscribe", "Home")'
Also you are saying that the error callback is always hit but you didn't say what you observed in FireBug or Chrome Developer toolbar when you tried to analyze the AJAX request. If you had done this you would have seen the exact cause of failure for the request because you would have seen what request is sent to the server and what response does the server sends back to the client.
The following is my jQuery ajax snippet that works. Your controller looks right. I assume you have verified it is actually getting called by using a breakpoint.
var p = {
email: $('#sube').val()
};
$.ajax({
url: '#Url.Action("Subscribe", "Home")'
type: 'POST',
data: JSON.stringify(p),
dataType: "text json",
contentType: "application/json",
success: function (data) {
// get the result and do some magic with it
alert(data.foo);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});

jQuery Ajax Call, give offline/ "not able to connect" message

Yes, i have a normal ajax call that calls imback.php, that checks for new stuff if you have been blur for 50 sec.
Now if you disconnects from the internet, and when you get on focus, it will not be able to get imback.php.(i think its 404 error) So i would like to make a offline msg/timeout thing, so it alerts "You have no internet connection or something else went wrong".
How can i do that?
$.ajax({
url: 'imback.php',
success:function(msg) {
$('.NewStuffSinceActive').prepend(msg);
}
})
You can use the error callback for this:
$.ajax({
url: 'imback.php',
success: function(msg) {
$('.NewStuffSinceActive').prepend(msg);
},
error: function(xhr, status, error) {
alert("An error occured: " + error);
}
})

Check status of a jQuery ajax request

It seems that the success, error, and complete callbacks only fire when the ajax request is able to get some response from the server.
So if I shut down the server the following error callback is not executed and the request fails silently.
$.ajax({
type: "GET",
url: "http://localhost:3000/",
dataType: "script",
success: function() {
alert("success");
},
error: function() {
alert("error");
}
});
What's the best way to throw an error when the server can't be reached at all.
Edit - From what I've tried and read it appears that jQuery's built in error handling doesn't work with JSONP, or dataType: "script". So I'm going to try setting a manual timeout.
Edit - Did a little more research and it looks like not only does the ajax error callback not work, but you can't abort an ajax request with dataType script or jsonp, and those requests ignore the timeout setting.
There is an alternative - the jquery-jsonp plugin, but it uses hidden iframes which I'd rather avoid. So I've settled on creating a manual timeout as suggested below. You can't abort the request if it times out, which means the script may still load even after the timeout, but at least something will fire if the server is unavailable.
You can use a setTimeout, and clear it with clearTimeout in the complete handler.
var reqTimeout = setTimeout(function()
{
alert("Request timed out.");
}, 5000);
var xhr = $.ajax({
type: "GET",
url: "http://localhost:3000/",
dataType: "script",
success: function() {
alert("success");
},
error: function() {
alert("error");
},
complete: function() {
clearTimeout(reqTimeout);
}
});
jQuery.ajax already has a timeout preference and it should call your error handler should the request time out. Check out the fantastic documentation which says — I’d quote it here, emphasis mine:
timeoutNumber
Set a local timeout (in milliseconds) for the request…
and:
error (XMLHttpRequest, textStatus, errorThrown) Function
A function to be called if the request fails. The function is passed three arguments: The XMLHttpRequest object, a string describing the type of error that occurred and an optional exception object, if one occurred. Possible values for the second argument (besides null) are "timeout", "error", "notmodified" and "parsererror". This is an Ajax Event.
error: function (jqXHR, textStatus, errorthrown) {
if (jqXHR.readyState == 0) {
//Network error, i.e. server stopped, timeout, connection refused, CORS, etc.
}
else if (jqXHR.readyState == 4) {
//HTTP error, i.e. 404 Not found, Internal Server 500, etc.
}
}
Use readyState of XMLHttpRequest to determine the status of the ajax request.
'readyState' holds the status of the XMLHttpRequest.
0: request not initialized
1: server connection established
2: request received
3: processing request
4: request finished and response is ready
If I remember correctly, jQuery throws exceptions. Thus, you should be able to work with a try { ... } catch() { ... } and handle it there.
You can use Jquery's AjaxSetup to handle your error handling.
$.ajax({
type: "GET",
url: "http://localhost:3000/",
dataType: "script",
success: function () {
alert("success");
}, error: function () {
alert("error");
}
//AJAX SETUP "error"//
$.ajaxSetup({
"error": function (XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest + ' ' + textStatus + ' ' + errorThrown); //however you want
}
});
in ie8,can use:
success: function(data, textStatus, XMLHttpRequest) {
if("success"==textStatus&&XMLHttpRequest){
alert("success");
}else{
alert("server down");
}
}
but it's can't work on chrome,firefox...
i tried

Resources