HTTP 状态码 0 是否有任何意义?
似乎当您从浏览器中的脚本发出 XMLHttpRequest 时,如果浏览器设置为脱机工作或拔出网线,则请求完成并出现错误并且状态 = 0.0 不是列在允许的 HTTP 状态代码中.
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.
状态码 0 是什么意思?对于所有浏览器和所有 HTTP 客户端实用程序,这是否意味着相同的事情?它是 HTTP 规范的一部分还是其他协议规范的一部分?似乎是根本无法发出HTTP请求,可能是因为无法解析服务器地址.
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"?
我应该补充一点,当设置为脱机工作"时,我在 FireFox 中看到了该行为,但在设置为脱机工作"时,在 Microsoft Internet Explorer 中看不到.在 IE 中,用户会看到一个对话框,提供在线选项.FireFox 在返回错误之前不会通知用户.
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.
我问这个是为了响应显示更好的错误消息"的请求.Internet Explorer 的功能很好.它告诉用户是什么导致了问题,并为他们提供了修复它的选项.为了提供与 FireFox 等效的 UX,我需要推断问题的原因并通知用户.那么我总共可以从状态 0 中推断出什么?它有普遍意义还是什么也没告诉我?
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?
推荐答案
简答
这不是 HTTP 响应代码,但 WhatWG 将其记录为 XMLHttpRequest
或 Fetch 响应的状态属性的有效值.
Short Answer
It's not a HTTP response code, but it is documented by WhatWG as a valid value for the status attribute of an XMLHttpRequest
or a Fetch response.
广义上讲,它是在没有真实 HTTP 状态代码要报告和/或发送请求或接收响应时发生错误时使用的默认值.出现这种情况的可能场景包括但不限于:
Broadly speaking, it is a default value used when there is no real HTTP status code to report and/or an error occurred sending the request or receiving the response. Possible scenarios where this is the case include, but are not limited to:
- 请求尚未发送或已中止.
- 浏览器仍在等待接收响应状态和标头.
- 请求期间连接断开.
- 请求超时.
- 请求遇到无限重定向循环.
- 浏览器知道响应状态,但由于与 同源政策.
首先,重申一下:0 不是 HTTP 状态码.RFC 7231 第 6.1 节 中有完整的列表'不包括 0,第 6 节的介绍清楚地指出
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
status-code 元素是一个三位整数代码
The status-code element is a three-digit integer code
哪个不是 0.
然而,记录了作为 XMLHttpRequest 对象的 .status
属性的值的 0,尽管跟踪所有相关细节有点棘手.我们从 https://xhr.spec.whatwg.org/#the-status 开始-attribute,记录 .status
属性,简单说明:
However, 0 as a value of the .status
attribute of an XMLHttpRequest object is documented, although it's a little tricky to track down all the relevant details. We begin at https://xhr.spec.whatwg.org/#the-status-attribute, documenting the .status
attribute, which simply states:
status
属性必须返回 响应状态.
这听起来可能很空洞且重复,但实际上这里有信息!请记住,本文档在这里讨论的是 XMLHttpRequest
的 .response
属性,而不是响应,因此这告诉我们 XHR 对象上的状态定义是延迟的到 Fetch 规范中响应状态的定义.
That may sound vacuous and tautological, but in reality there is information here! Remember that this documentation is talking here about the .response
attribute of an XMLHttpRequest
, not a response, so this tells us that the definition of the status on an XHR object is deferred to the definition of a response's status in the Fetch spec.
但是什么响应对象呢?如果我们实际上还没有收到回复怎么办?响应"一词上的内联链接将我们带到 https://xhr.spec.whatwg.org/#response,其中解释:
But what response object? What if we haven't actually received a response yet? The inline link on the word "response" takes us to https://xhr.spec.whatwg.org/#response, which explains:
XMLHttpRequest
具有关联的响应.除非另有说明,否则这是一个网络错误.
所以我们得到的响应状态默认是网络错误.通过搜索在 XHR 规范中使用的短语 set response to",我们可以看到它被设置在五个地方:
So the response whose status we're getting is by default a network error. And by searching for everywhere the phrase "set response to" is used in the XHR spec, we can see that it's set in five places:
网络错误,当:
To a network error, when:
open()
方法 被调用,或者- 响应的 body 的 stream 是 errored (请参阅
send()
方法) - 设置了 超时标志,导致 请求错误步骤运行
abort()
方法 被调用,导致 请求错误步骤 运行
- the
open()
method is called, or - the response's body's stream is errored (see the algorithm described in the docs for the
send()
method) - the timed out flag is set, causing the request error steps to run
- the
abort()
method is called, causing the request error steps to run
对于使用 Fetch 发送请求产生的响应,通过 Fetch 处理响应 任务(如果 XHR 请求是异步的)或 Fetch 处理响应体结束 任务(如果 XHR 请求是同步的).
To the response produced by sending the request using Fetch, by way of either the Fetch process response task (if the XHR request is asychronous) or the Fetch process response end-of-body task (if the XHR request is synchronous).
查看Fetch 标准,我们可以看到:
网络错误是response 其 status 总是 0
因此,在 XHR 规范规定响应应设置为网络错误的任何情况下,我们都可以立即知道 XHR 对象的状态为 0.(有趣的是,这包括正文的流被错误"的情况,Fetch 规范告诉我们,在收到状态之后解析正文时可能会发生这种情况 - 所以理论上我认为这是可能的将 XHR 对象的状态设置为 200,然后在接收主体时遇到内存不足错误或其他问题,因此将其状态更改回 0.)
so we can immediately tell that we'll see a status of 0 on an XHR object in any of the cases where the XHR spec says the response should be set to a network error. (Interestingly, this includes the case where the body's stream gets "errored", which the Fetch spec tells us can happen during parsing the body after having received the status - so in theory I suppose it is possible for an XHR object to have its status set to 200, then encounter an out-of-memory error or something while receiving the body and so change its status back to 0.)
我们还注意到在 Fetch 标准中存在一些其他响应类型,它们的状态定义为 0,它们的存在与跨域请求和同源策略有关:
We also note in the Fetch standard that a couple of other response types exist whose status is defined to be 0, whose existence relates to cross-origin requests and the same-origin policy:
不透明的过滤响应是 过滤响应,其 ...状态是 0
...
An opaque filtered response is a filtered response whose ... status is
0
...
不透明重定向过滤响应是 过滤响应,其 ... 状态为 0
...
An opaque-redirect filtered response is a filtered response whose ... status is 0
...
(省略了有关这两种响应类型的其他各种详细信息).
(various other details about these two response types omitted).
但除此之外,还有很多情况是 Fetch 算法(而不是我们已经看过的 XHR 规范)要求浏览器返回网络错误!实际上,短语return a network error"很重要.在 Fetch 标准中出现 40 次.我不会尝试在这里列出所有 40 个,但我注意到它们包括:
But beyond these, there are also many cases where the Fetch algorithm (rather than the XHR spec, which we've already looked at) calls for the browser to return a network error! Indeed, the phrase "return a network error" appears 40 times in the Fetch standard. I will not try to list all 40 here, but I note that they include:
- 请求的方案无法识别的情况(例如,尝试向 madeupscheme://foobar.com 发送请求)
- 非常模糊的指令如有疑问,请返回网络错误."在处理 ftp://和 file://URL 的算法中
- 无限重定向:如果请求的重定向计数为 20,则返回网络错误."
- 一堆与CORS相关的问题,例如如果httpRequest的响应污染不是cors";并且请求和响应返回阻塞的跨域资源策略检查,然后返回网络错误."
- 连接失败:如果连接失败,返回网络错误."
- The case where the request's scheme is unrecognised (e.g. trying to send a request to madeupscheme://foobar.com)
- The wonderfully vague instruction "When in doubt, return a network error." in the algorithms for handling ftp:// and file:// URLs
- Infinite redirects: "If request’s redirect count is twenty, return a network error."
- A bunch of CORS-related issues, such as "If httpRequest’s response tainting is not "cors" and the cross-origin resource policy check with request and response returns blocked, then return a network error."
- Connection failures: "If connection is failure, return a network error."
换句话说:每当出现问题时其他除了从服务器获取真正的 HTTP 错误状态代码(如 500 或 400)之外,您最终会在 XHR 对象上获得状态属性 0 或在浏览器中获取响应对象.规范中列举的可能的具体原因数量众多.
In other words: whenever something goes wrong other than getting a real HTTP error status code like a 500 or 400 from the server, you end up with a status attribute of 0 on your XHR object or Fetch response object in the browser. The number of possible specific causes enumerated in spec is vast.
最后:如果您出于某种原因对规范的历史感兴趣,请注意此答案已在 2020 年完全重写,您可能对 此答案的先前修订版,在将这些被替换为此答案所指的 WhatWG 规范越现代、越复杂.
Finally: if you're interested in the history of the spec for some reason, note that this answer was completely rewritten in 2020, and that you may be interested in the previous revision of this answer, which parsed essentially the same conclusions out of the older (and much simpler) W3 spec for XHR, before these were replaced by the more modern and more complicated WhatWG specs this answers refers to.
相关文章