How to get error details from xmlhttprequest? - javascript

I'm trying to get some more information about why my request failed. It goes through the standard phases (I can see receiving headers (state 2) for a while). Then it notifies about readyState=4, status=0 and no statusText set.
How can I get some more information about what happened and why?

If this is a simple website AJAX request you can use Firebug to look at all the parameters, it will not tell you what happens in code but can help you maybe figure out what is wrong with the post/get request to the server, this way maybe this is an issue with the back-end or a bug in the request uri or parameters
And in general it is a useful tool to have which is free

Related

Problem with $.json return status 0 in Cordova when run from browser [duplicate]

For some reason, while using AJAX (with my dashcode developed application) the browser just stops uploading and returns status codes of 0. Why does this happen?
Another case:
It could be possible to get a status code of 0 if you have sent an AJAX call and a refresh of the browser was triggered before getting the AJAX response. The AJAX call will be cancelled and you will get this status.
In my experience, you'll see a status of 0 when:
doing cross-site scripting (where access is denied)
requesting a URL that is unreachable (typo, DNS issues, etc)
the request is otherwise intercepted (check your ad blocker)
as above, if the request is interrupted (browser navigates away from the page)
Same problem here when using <button onclick="">submit</button>. Then solved by using <input type="button" onclick="">
Status code 0 means the requested url is not reachable. By changing http://something/something to https://something/something worked for me. IE throwns an error saying "permission denied" when the status code is 0, other browsers dont.
It is important to note, that ajax calls can fail even within a session which is defined by a cookie with a certain domain prefixed with www. When you then call your php script e.g. without the www. prefix in the url, the call will fail and viceversa, too.
Because this shows up when you google ajax status 0 I wanted to leave some tip that just took me hours of wasted time... I was using ajax to call a PHP service which happened to be Phil's REST_Controller for Codeigniter (not sure if this has anything to do with it or not) and kept getting status 0, readystate 0 and it was driving me nuts. I was debugging it and noticed when I would echo and return instead of exit the message I'd get a success. Finally I turned debugging off and tried and it worked. Seems the xDebug debugger with PHP was somehow modifying the response. If your using a PHP debugger try turning it off to see if that helps.
I found another case where jquery gives you status code 0 -- if for some reason XMLHttpRequest is not defined, you'll get this error.
Obviously this won't normally happen on the web, but a bug in a nightly firefox build caused this to crop up in an add-on I was writing. :)
This article helped me. I was submitting form via AJAX and forgotten to use return false (after my ajax request) which led to classic form submission but strangely it was not completed.
"Accidental" form submission was exactly the problem I was having. I just removed the FORM tags altogether and that seems to fix the problem. Thank you, everybody!
I had the same problem, and it was related to XSS (cross site scripting) block by the browser. I managed to make it work using a server.
Take a look at: http://www.daniweb.com/web-development/javascript-dhtml-ajax/threads/282972/why-am-i-getting-xmlhttprequest.status0
We had similar problem - status code 0 on jquery ajax call - and it took us whole day to diagnose it. Since no one had mentioned this reason yet, I thought I'll share.
In our case the problem was HTTP server crash. Some bug in PHP was blowing Apache, so on client end it looked like this:
mirek#toccata:~$ telnet our.server.com 80
Trying 180.153.xxx.xxx...
Connected to our.server.com.
Escape character is '^]'.
GET /test.php HTTP/1.0
Host: our.server.com
Connection closed by foreign host.
mirek#toccata:~$
where test.php contained the crashing code.
No data returned from the server (not even headers) => ajax call was aborted with status 0.
In my case, it was caused by running my django server under http://127.0.0.1:8000/ but sending the ajax call to http://localhost:8000/. Even though you would expect them to map to the same address, they don't so make sure you're not sending your requests to localhost.
In our case, the page link was changed from https to http. Even though the users were logged in, they were prevented from loading with AJAX.
In my case, setting url: '' in ajax settings would result in a status code 0 in ie8.. It seems ie just doesn't tolerate such a setting.
For me, the problem was caused by the hosting company (Godaddy) treating POST operations which had substantial response data (anything more than tens of kilobytes) as some sort of security threat. If more than 6 of these occurred in one minute, the host refused to execute the PHP code that responded to the POST request during the next minute. I'm not entirely sure what the host did instead, but I did see, with tcpdump, a TCP reset packet coming as the response to a POST request from the browser. This caused the http status code returned in a jqXHR object to be 0.
Changing the operations from POST to GET fixed the problem. It's not clear why Godaddy impose this limit, but changing the code was easier than changing the host.
I think I know what may cause this error.
In google chrome there is an in-built feature to prevent ddos attacks for google chrome extensions.
When ajax requests continuously return 500+ status errors, it starts to throttle the requests.
Hence it is possible to receive status 0 on following requests.
In an attempt to win the prize for most dumbest reason for the problem described.
Forgetting to call
xmlhttp.send(); //yes, you need this pivotal line!
Yes, I was still getting status returns of zero from the 'open' call.
In my case, I was getting this but only on Safari Mobile. The problem is that I was using the full URL (http://example.com/whatever.php) instead of the relative one (whatever.php). This doesn't make any sense though, it can't be a XSS issue because my site is hosted at http://example.com. I guess Safari looks at the http part and automatically flags it as an insecure request without inspecting the rest of the URL.
In my troubleshooting, I found this AJAX xmlhttpRequest.status == 0 could mean the client call had NOT reached the server yet, but failed due to issue on the client side. If the response was from server, then the status must be either those 1xx/2xx/3xx/4xx/5xx HTTP Response code. Henceforth, the troubleshooting shall focus on the CLIENT issue, and could be internet network connection down or one of those described by #Langdon above.
In my case, I was making a Firefox Add-on and forgot to add the permission for the url/domain I was trying to ajax, hope this saves someone a lot of time.
Observe the browser Console while making the request, if you are seeing "The Same Origin Policy disallows reading the remote resource at http ajax..... reason: cors header ‘access-control-allow-origin’ missing" then you need to add "Access-Control-Allow-Origin" in response header. exa: in java you can set this like response.setHeader("Access-Control-Allow-Origin", "*") where response is HttpServletResponse.

can't send PUT to Philips Hue (same origin policy)

I'm trying to send a PUT-request to a Philips Hue bridge, so I can change the current state in which the lamp is. I do this from a webserver on my PC. With CORS I already managed to send GET and POST- request, but if I send a PUT I get an error that tells "method not found in Access-Control-Allow-Methods". I'm pretty sure that would make no sense to block just that method.
I'm using that code to do so, it is the same as the code for GET and POST, just the if clause is not needed.
var lightReq = new XMLHttpRequest();
if ("withCredentials" in lightReq) {
lightReq.open('PUT',stringChange,true);
if (value == false) {
lightReq.send("{\"on\":true}");
}
else {
lightReq.send("{\"on\":false}");
}
}
Maybe someone had a similar problem and got a solution, or there are steps I should check. I'm glad for every help.
EDIT:
Here is a screenshot of the header, it shows that the PUT-method should be accepted.
EDIT2:
For roryhewitt here is what you asked for, i think:
Best Regards,
Adrian
It looks from your screenshot as if that's the response to a POST request (I'm looing at the Anfragemethode field)?
Most of those CORS response headers (except ACAC) should only be returned in the response to a preflight OPTIONS request - they have no 'meaning' if they are returned in the response to any other request. That's the 'fault' of the bridge, though, not of anything you're doing in the browser code.
Anyway, when your JS code makes a PUT request via XMLHttpRequest, if you look at the network traffic from your browser, you should see an OPTIONS requests (CORS preflight) followed by your PUT request. If you only see the OPTIONS request, can you provide the response headers for that request?

Angular HTTP 'get' request 304 error

I was building angular's official 'heroes tutorial app' and instead of using their in-memory-data code, i tried using a json.placeholders (users) api so the app would be more real-world example.
Problem is when i change the official codes example url(in-memory-url) with the json.placeholder's api it just doesnt list the names and i checked the chrome dev console-network tab it shows status code 304,
By the way I am only trying to make a get request part of the tutorial, here is the error:
Request URL:https://jsonplaceholder.typicode.com/users
Request Method:GET
Status Code:304
Remote Address:104.31.87.157:443
Referrer Policy:no-referrer-when-downgrade
Edit:
So i managed to list users from json.placeholder on the app with using observables from rxjs, then i changed it back to promise method official website shows that way and still not listing. Maybe it's something about the angular's promises i dont know.
However browsers network still showing 304 status. I am worrying that this could be a problem and it shouldn't be this way. So any help would be appreciated thanks.
HTTP 304 header code means "Not modified", it's not an error. According to the RFC 2616 of HTTP 1.1, the server only sends back headers, not the response which tells the browser to use the response that it had already in cache.
On the other hand, angular will always put 200 in status (even if it is a 304) and you shouldn't have to bother about keeping up to date your data, since you retrieve the fresher value each time (without bothering if it's from a cache in the server or fresh data from the server)
Id Add a random query string behind your url, that takes timestamp as the value. This way, each request will be considered a fresh one
Moreover id refer you to this topic

How to handle CORS error code?

Edit: I just realized this is a duplicate of Recommended solution for AJAX, CORS, Chrome & HTTP error codes (401,403,404,500), and he tried the idea I propose at the end. But I can't tell if he succeeded (dud user?), and no one else has posted a solution or even a comment, so I think it's worth fishing for new answers.
Problem:
I send a properly-executed (edit: IMproperly-executed. End of story...) CORS request.
The server receives the request and attempts to process it.
The server returns an error response, for example a 422 Unprocessable Entity, along with JSON information about the errors. The idea is that my app could receive this error information and handle it appropriately in the UI.
The browser blocks my error handler from getting the response content, or even getting the status code.
Showing that the browser received the 401 status code but treated it as a CORS security error:
The response object, showing that my code cannot access the response data (data: "", status: 0):
How have other people handled this limitation? My best guess right now is to hijack an HTTP "success" code (2XX) as an error code, and then include the error information in the response. This prevents me from using the ajax error handlers in a normal way, but I'm handling this as a global ajax filter anyway, so this filter would capture the deviant success code and trigger the error handlers instead.
The console message indicates that the server isn't sending the required Access-Control-Allow-Origin header when it sends the 401 response code.
You won't be able to use the CORS error handler to inject content into the DOM unless you fix that.
The server is likely sending the header correctly on responses with a 200 response code. It needs to do it for other response codes, though, if you wish to use data from those response codes.
Fix that on the server end before making design compromises on the client side. That may solve your problem straight away.
It seems it's an opaque response where you can't obtain the headers or the response. And everything is set to null or empty.
https://developer.mozilla.org/en-US/docs/Web/API/Response/type
Or maybe in the server you should add:
Access-Control-Allow-Origin: *
Very late answer but in case someone wants to check whether an error occurred while sending an XMLHttpRequest and then take appropriate actions (on the CLIENT side), then this is a quick workaround:
try{
request.send();
}catch(err){
if(e.toString().startsWith("NetworkError")){
//pasre the string to check error code
//and take appropriate actions
}
}
This is needed because the onreadystatechange function doesn't get executed when a NetworkError occurs and, in fact, the whole script is terminated.

Is there any way to do cross-domain request from javascript and access the type of error response(401, 404, etc.) that it might generate

I tried using jquery.ajax but it fails silently whenever there is an error response
No, this is not possible without any workaround.
When making cross-domain (JSONP) requests, jQuery doesn't trigger an error event, see this answer on SO.
If it's sufficient for you to know that there was an error (without getting additional info), you could try something like this, combined with this.
If you really need the HTTP status code, you will have to work server-side, i.e. use your own server as a proxy to get the cross-domain resource. Then you can send additional info to JS using the JSONP callback; see this solution on SO.
Sorry for posting so many links, but I guess that's better than quotations... ;)

Categories