I've a server that returns HTTP status code 200, 201, and 202 from the same url. In Chrome, I've confirmed with the Network debugging panel that the Status Code is what I expect it to be (i.e. 200, 201 or 202). I rely on that status code to determine the next step.
I'd expect that the callbacks for jQuery (version 1.5.2) AJAX requests to set jqxhr.status to the status code that the server sends. However, the status code is always 200, even if the code sent by the server is 201 or 202.
In other words, the following code prints Code: 200 regardless of what the server sends.
$.get(url, {}, function (data, textStatus, xhr ) {
alert("Code: " + xhr.status);
});
Why is this happening, and more importantly, how can one get the actual status code in a jQuery AJAX callback for $.get or $.ajax?
Thank you for reading.
From what I have experienced jQuery is just not set up very well for handling actual status codes in the response. You can try just doing a manual AJAX call using some good old bare bones JS and handle the status yourself.
Here are a few tutorials on how to do so.
http://www.degraeve.com/reference/simple-ajax-example.php
http://www.w3schools.com/ajax/default.asp
request.status is where you should be able to access the status code in your request object. Here is another page showing a little bit about how to access even more granular information about the status of the request.
http://www.ibm.com/developerworks/web/library/wa-ajaxintro3/
Hope that helps you nail it!
Related
I'm using appAPI.request to make ajax calls to an external web API. This works very well, but the API sends HTTP status codes other than 200 when something goes wrong. It also sends the error message/code when this happens. As the onFailure callback does only returns the http error code, but not the response message, i'm unable to read the error message sent by the server. Is there any way to retrieve the response message when onFailure gets called?
As of now, the HTTP response text is not currently available in the onFailure callback. However, as we are constantly working on improvements, we will add this to our API in future releases.
Disclaimer: I am a Crossrider employee
I have the following.
AJAX request made to server from mydomain.blah.com
Server returns 302 but to a slight different domain blah.com not mydomain.blah.com
Browser appears to mangle response. Instead of the 302 coming into my error callback a response with no response body and no status code is returned.
Further details
Looking at request in IE 10 it is marked as aborted.
In FF , firebug shows the 302 coming back but it never been handled.
To complicate matters (although I don't this is relevant) there are multiple ajax requests sent over.
The reason why the 302 is returned is because my server session is timed out and I am being redirected to a login page. I don't have much control over the server.
I want to get the response code 302 sent from my server into my error callback. This is what I want to achieve.
The ajax calls are being made using JQuery.
Any help appreciated.
If it is offical policy for browsers to "mangle" 302 responses to difference domains from ajax calls then if anyone could provide a reference that would be cool. Then I'd know there is not much I can do about this.
If it possible to tell (within javascript execution) if a GET XMLHTTPRequest hit the browser cache instead of getting its response from the server?
From the XMLHttpRequest spec:
For 304 Not Modified responses that are a result of a user agent
generated conditional request the user agent must act as if the server
gave a 200 OK response with the appropriate content.
In other words, the browser will always give status code 200 OK, even for requests that hit the browser cache.
However, the spec also says:
The user agent must allow author request headers to override automatic cache
validation (e.g. If-None-Match or If-Modified-Since), in which case
304 Not Modified responses must be passed through.
So, there is a workaround to make the 304 Not Modified responses visible to your JavaScript code.
When making an ajax request, You get the response code
if (request.readyState == 4) {
if (request.status == 200) { // this number.
...
status 200 means you are getting a fresh copy of the data:
The request has succeeded. The information returned with the response is dependent on the method used in the request -
status 304 means the data has not changed and you will get it from the browser cache:
If the client has performed a conditional GET request and access is allowed, but the document has not been modified, the server SHOULD respond with this status code.
Read more on Status Code
Update:
You can add a cache buster to your URL to guarantee that you always hit the server:
var ajaxUrl = "/path?cache="+(Math.random()*1000000);
From http://www.w3.org/TR/2012/WD-XMLHttpRequest-20121206/
For 304 Not Modified responses that are a result of a user agent
generated conditional request the user agent must act as if the server
gave a 200 OK response with the appropriate content. The user agent
must allow author request headers to override automatic cache
validation (e.g. If-None-Match or If-Modified-Since), in which case
304 Not Modified responses must be passed through. [HTTP]
I find this rather vague. My assumption would be if a resource is conditionally requested, you would see the 304 response code. But, as I explained in another comment (source: https://developers.google.com/speed/docs/best-practices/caching), there might not even be a request if the last response server http header for that resource had set Cache-Control: max-age or Expires set sometime in the future. In this case, I'm not sure what ought to happen.
This answer is based on the assumption that you mean browser only cache, with no 304's taking place (modified-since, etag etc).
Check how long the request took - if it was resolved from cache then it should take close to 0ms.
Do you use Firefox's Firebug?
Firebug has a "Net" panel with an "XHR" filtered view. You should be able to inspect the cache info via the request phase bar, checking the status and/or clicking the triangle to inspect "Headers".
Cached or not cached
Not all network requests are equal - some of them are loaded from the
browser cache instead of the network. Firebug provides status codes
for every request so you can quickly scan and see how effectively your
site is using the cache to optimize page load times.
Firebug Net Panel docs are here.
Chrome/Safari/Opera all have similar debugging tools. Just found a good list here (most should have tools to inspect XHR).
EDIT:
In order to somewhat redeem myself...
As ibu has answered, I'd also start by checking the status code of the response.
If you're using jQuery:
statusCode(added 1.5)
Map Default: {}
A map of numeric HTTP codes and functions to be called when the
response has the corresponding code. For example, the following will
alert when the response status is a 404:
$.ajax({
statusCode: {
404: function() {
alert("page not found");
}
}
});
If the request is successful, the status code functions take the same
parameters as the success callback; if it results in an error, they
take the same parameters as the error callback.
jQuery sure does make life easy. :)
To check from a browser such as Google Chrome, hit F12 to open DevTools, navigate to Network, refresh to grab some data, filter by XHR, then click on the correct XHR request. Click on the "headers" sub-tab, then look at Response Headers -> cache-control.
If it says things like no-cache and max-age=0, then you are not caching.
If it says private, then your browser is caching, but the server is not.
If it says public, then you are caching both server side and client side.
More info at Mozilla.org
I am implementing an application which relies upon communication between a JavaScript client and a server which knows how to respond to the client using JSONP notation.
I am attempting to handle the case in my Javascript client where my server returns with an http status code of 4xx or 5xx. Currently what I'm seeing is that the script is not evaluated as the browser believes it to be an error (which it is.) However, I still want to read what my server has to say in the event of this 4xx or 5xx response code in my JavaScript client.
I'm seeing that this does raise an error on the script tag element, but I'm concerned that this is not cross browser and will not be a robust solution.
Has anyone had any luck on still parsing a jsonp response even though the http status code is 4xx or 5xx?
I'm beginning to believe I should just use this "set a timeout" solution which "detects" a failure by stating the callback function to the jsonp request would complete within a certain time frame, and if it doesn't, there was an error.
EDIT: I'm temporarily always returning 200 status code when my server detects a jsonp client and then tunneling the error message/status in the json object returned. I was hoping to take advantage of the HTTP status codes but I'm thinking that is no-go for a javscript client.
JSONP is a hack to work-around cross-domain issues. When it works, it works well. But when it doesn't you don't have a way to figure out what went wrong.
setTimeout is another hack on top of the original one. If you must use JSONP and still need error detection (not handling), thats what you'd have to do. There isn't a better solution.
If you control the server, try to use alternatives such as Cross-Origin-Resource-Sharing (CORS), or Flash's crossdomain.xml to allow cross domain requests. If you don't control the server, you can proxy the response through your server to get better control.
One approach when using JSONP is to embed status information in the callback. So the callback function signature would look like
callback(result, status, message)
So if your call looks like
http://myurl.com/?callback=fn
generate code for a successful call that looks like
fn({"data":"my great data"}, 200)
and for an exceptional condition
fn(null, 500, "server error"}
You can check the status of the XHR object (if you are not using a JS library).
if(xhr.readyState == 4){
if(xhr.status == 200){
// good
}else if(xhr.status == 502){
// d'oh
}
}
If you are using jQuery, you can pass in a statusCode to handle special cases for $.ajax
I use jQuery to make an AJAX POST request to my server, which can return HTTP response with status 302. Then JavaScript just sends GET request to this URL, while I'd like to redirect user to URL in this response. Is this possible?
The accepted answer does not work for the reasons given. I posted a comment with a link to a question that described a hack to get round the problem of the 302 being transparently handled by the browser:
How to manage a redirect request after a jQuery Ajax call
However, it is a bit of a dirty hack and after much digging around I found what I think is a better solution - use JSON. In this case, you can make all responses to ajax requests have the code 200 and, in the body of the response, you add some sort of JSON object which your ajax response handler can then use in the appropriate manner.
I don't think so. The W3C says that HTTP redirects with certain status codes, including 302, must be transparently followed. Quoted below:
If the response is an HTTP redirect (status code 301, 302, 303 or
307), then it MUST be transparently followed (unless it violates
security or infinite loop precautions). Any other error (including a
401) MUST cause the object to use that error page as the response.
As an experiment, I tried doing Ajax requests from various browsers (Firefox 3.5, Chrome, IE8, IE7, IE6) to a server giving a 302 status code, and showing the status in the browser's request object. In every case, it showed up as 200.
In my problem reason was:
i was using localhost/Home/Test addres for testing the page. But ajax request code using 127.0.0.1/Home/AjaxRequest for url parameter. When the urls are different this error occurs.
maybe it helps someone :)
Rather than asking the Javascript code to Handle 302, it would be better to return a 500 with custom error code+ message on event of 302
function doAjaxCall() {
$.ajaxSetup({complete: onRequestCompleted});
$.get(yourUrl,yourData,yourCallback);
}
function onRequestCompleted(xhr,textStatus) {
if (xhr.status == 302) {
location.href = xhr.getResponseHeader("Location");
}
}