I believe status code of zero could mean many things. In my case I was receiving the status code of zero due to a user leaving the page before the request-response cycle could complete. You could also get a status code of zero if communication with the server failed. I have basically summarized this as a failure in out-bound communication from the sender. That would be why it also comes up with cross-site requests and other reasons dealing with the client side.
The W3 XMLHttpRequest specification section 4.8.1 states:
The status attribute must return the result of running these steps:
If the state is UNSENT or OPENED, return 0 and terminate these steps.
If the error flag is set, return 0 and terminate these steps.
Return the HTTP status code.
If I read the specification correctly, UNSENT and OPENED are states the request can be in prior to being sent. And the error flag is set if:
The error flag indicates some type of network error or request abortion ...
The problem I have with this status code is if a request is aborted by the user from navigating away, I do not consider this an error condition as it is a deliberate action by the user. Network issues I do consider an error. For example, if the user invokes an action that results in an ajax request which has an error handler to redirect them to an error page. If the user were to leave the current page, thus aborting the request, from a usability standpoint, it doesn't make sense to redirect them to the error page. The implementation of the specification is fine except for that I have yet to determine a method of knowing that a status code of zero came from an aborted request or for some other reason. If I were able to determine the difference, I would be able to take appropriate action.
EDIT: 03/18/2014
In response to comment by @ariera on Aug 9 2013, I'm supplying the rough description of what the workaround was. However, the problem is that it has been some time since i resolved this and my memory is vague.
If i remember correctly, the idea around determining if the status code of 0 was due to the user indirectly aborting the request was to put the error handling code in its own callback separate from the error callback. Then in your error callback, you check to see if the status code is zero. If it is, call your error callback in a timeout delay, otherwise call your error callback. The idea here is that if the error code is zero, then putting a delay in the handling of that error allows the browser to actually perform the navigation. Allowing the browser to perform the navigation should clear any executing JavaScript and thus the error handler will not fire.
Now this is a kludge, and may not even work as again, I don't really remember the intricacies of the issues, but hopefully it leads someone else down the correct path.