Does an HTTP Status code of 0 have any meaning?

2019-01-03 04:57发布

It appears that when you make an XMLHttpRequest from a script in a browser, if the browser is set to work offline or if the network cable is pulled out, the request completes with an error and with status = 0. 0 is not listed among permissible HTTP status codes.

What does a status code of 0 mean? Does it mean the same thing across all browsers, and for all HTTP client utilities? Is it part of the HTTP spec or is it part of some other protocol spec? It seems to mean that the HTTP request could not be made at all, perhaps because the server address could not be resolved.

What error message is appropriate to show the user? "Either you are not connected to the internet, or the website is encountering problems, or there might be a typing error in the address"?

I should add to this that I see the behavior in FireFox when set to "Work Offline", but not in Microsoft Internet Explorer when set to "Work Offline". In IE, the user gets a dialog giving the option to go online. FireFox does not notify the user before returning the error.

I am asking this in response to a request to "show a better error message". What Internet Explorer does is good. It tells the user what is causing the problem and gives them the option to fix it. In order to give an equivalent UX with FireFox I need to infer the cause of the problem and inform the user. So what in total can I infer from Status 0? Does it have a universal meaning or does it tell me nothing?

6条回答
冷血范
2楼-- · 2019-01-03 05:15

Know it's an old post. But these issues still exist.

Here are some of my findings on the subject, grossly explained.

"Status" 0 means one of 3 things, as per the XMLHttpRequest spec:

  • dns name resolution failed (that's for instance when network plug is pulled out)

  • server did not answer (a.k.a. unreachable or unresponding)

  • request was aborted because of a CORS issue (abortion is performed by the user-agent and follows a failing OPTIONS pre-flight).

If you want to go further, dive deep into the inners of XMLHttpRequest. I suggest reading the ready-state update sequence ([0,1,2,3,4] is the normal sequence, [0,1,4] corresponds to status 0, [0,1,2,4] means no content sent which may be an error or not). You may also want to attach listeners to the xhr (onreadystatechange, onabort, onerror, ontimeout) to figure out details.

From the spec (XHR Living spec):

const unsigned short UNSENT = 0;
const unsigned short OPENED = 1;
const unsigned short HEADERS_RECEIVED = 2;
const unsigned short LOADING = 3;
const unsigned short DONE = 4;
查看更多
劳资没心,怎么记你
3楼-- · 2019-01-03 05:19

from documentation http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute means a request was cancelled before going anywhere

查看更多
Anthone
4楼-- · 2019-01-03 05:19

Since iOS 9, you need to add "App Transport Security Settings" to your info.plist file and allow "Allow Arbitrary Loads" before making request to non-secure HTTP web service. I had this issue in one of my app.

查看更多
乱世女痞
5楼-- · 2019-01-03 05:28

Yes, some how the ajax call aborted. The cause may be following.

  1. Before completion of ajax request, user navigated to other page.
  2. Ajax request have timeout.
  3. Server is not able to return any response.
查看更多
ゆ 、 Hurt°
6楼-- · 2019-01-03 05:31

status 0 appear when an ajax call was cancelled before getting the response by refreshing the page or requesting a URL that is unreachable.

this status is not documented but exist over ajax and makeRequest call's from gadget.io.

查看更多
萌系小妹纸
7楼-- · 2019-01-03 05:32

Short Answer

It's not a HTTP response code, but it is documented by W3 as a valid value for the status attribute of an XMLHttpRequest (and thus also of a jqXHR object, for jQuery users).

It covers a whole swathe of possible situations in which there's no real HTTP response code available to report, either because you haven't sent the request, you explicitly aborted it, the page is unloading, or x went wrong for one of many possible values of x.

Long Answer

First, to reiterate: 0 is not a HTTP status code. There's a complete list of them in RFC 7231 Section 6.1, that doesn't include 0, and the intro to section 6 states clearly that

The status-code element is a three-digit integer code

which 0 is not.

However, 0 as a value of the status attribute of an XMLHttpRequest object is documented. From documentation at http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute:

4.7.1 The status attribute

The status attribute must return the result of running these steps:

  1. If the state is UNSENT or OPENED, return 0.

  2. If the error flag is set, return 0.

  3. Return the HTTP status code.

We can dig deeper into the spec and find out just what those conditions for returning 0 mean. From http://www.w3.org/TR/XMLHttpRequest/#states:

4.5 States

...

UNSENT (numeric value 0)

The object has been constructed.

OPENED (numeric value 1)

The open() method has been successfully invoked. During this state request headers can be set using setRequestHeader() and the request can be made using the send() method.

...

The error flag indicates some type of network error or fetch termination. It is initially unset.

It's also relevant to note that the next possible state after UNSENT and OPENED is HEADERS_RECEIVED:

HEADERS_RECEIVED (numeric value 2)

All redirects (if any) have been followed and all HTTP headers of the final response have been received. Several response members of the object are now available.

Putting this all together, the short answer is that 0 is simply what gets returned by the status attribute of an XMLHttpRequest object when there is no real status code to return, because either:

  • The request hasn't yet been sent, or
  • The request has been sent but the headers of the response have not yet been received, or
  • One of many possible circumstances have occurred, listed in the docs, that have caused the "error flag" to be set.

Okay, but what errors can cause this mysterious "error flag" to be set? If you CTRL-F for 'error flag' in the W3 documentation, you will find that it gets unset upon sending the request, and it only ever gets set as part of the algorithm to "terminate the request". Looking for all the places that algorithm is invoked, you'll find that it happens when:

  • The request is opened (or re-opened) with the open() method
  • The request is garbage collected (e.g. when leaving the page)
  • The request is aborted with the abort() method
  • A 'request error' happens, which can happen when one of the following situations occurs:

    • A network error occurs, which can happen if

      • There's an infinite redirect loop
      • There is/are

        DNS errors, TLS negotiation failure, or other type of network error

      • The request was a CORS request, and the response cannot be shared
    • An abort error occurs, which can only happen if

      The end user cancels the request

      whatever that means. I don't know of any browser that shows users when AJAX requests are occurring and gives them the opportunity to cancel them explicitly, so I think this one is - at least today - irrelevant.

    • A timeout error occurs, which means, reasonably enough, that

      timeout is not 0 and since the request started the amount of milliseconds specified by timeout has passed

As far as XMLHttpRequest goes, that's everything.

Beyond XMLHttpRequest, I would speculate that HTTP libraries in languages outside of JavaScript may well be using a 0 status code similarly, as a default value when no status code has been received from the server.

查看更多
登录 后发表回答