【问题标题】:Does an HTTP Status code of 0 have any meaning?HTTP 状态码 0 是否有任何意义?
【发布时间】:2011-04-19 01:01:11
【问题描述】:

当您从浏览器中的脚本发出 XMLHttpRequest 时,如果将浏览器设置为脱机工作或拔出网线,则请求完成并出现错误并且状态 = 0。0 不是列在允许的 HTTP 状态代码中。

状态码 0 是什么意思?对于所有浏览器和所有 HTTP 客户端实用程序,这是否意味着相同的事情?它是 HTTP 规范的一部分还是其他协议规范的一部分?好像是根本无法发出HTTP请求,可能是因为无法解析服务器地址。

什么错误信息适合向用户显示? “要么您没有连接到互联网,要么网站遇到问题,或者地址输入错误”?

我应该补充一点,当设置为“脱机工作”时,我在 FireFox 中看到了该行为,但在设置为“脱机工作”时,在 Microsoft Internet Explorer 中看不到。在 IE 中,用户会看到一个对话框,提供在线选项。 FireFox 在返回错误之前不会通知用户。

我问这个是为了响应“显示更好的错误消息”的请求。 Internet Explorer 的功能很好。它告诉用户是什么导致了问题,并为他们提供了修复它的选项。为了提供与 FireFox 等效的 UX,我需要推断问题的原因并通知用户。那么我总共可以从状态 0 中推断出什么?它有普遍意义还是什么也没告诉我?

【问题讨论】:

标签: ajax http browser xmlhttprequest


【解决方案1】:

简答

它不是 HTTP 响应代码,但 WhatWG 将其记录为 XMLHttpRequest 或 Fetch 响应的状态属性的有效值。

广义上讲,它是在没有真实 HTTP 状态代码要报告和/或发送请求或接收响应时发生错误时使用的默认值。出现这种情况的可能场景包括但不限于:

  • 请求尚未发送或已中止。
  • 浏览器仍在等待接收响应状态和标头。
  • 请求期间连接断开。
  • 请求超时。
  • 请求遇到无限重定向循环。
  • 浏览器知道响应状态,但由于与Same-origin Policy 相关的安全限制,您无法访问它。

长答案

首先,重申一下:0 不是 HTTP 状态码。在RFC 7231 Section 6.1 中有完整的列表,不包括 0,第 6 节的介绍清楚地指出

status-code 元素是一个三位整数代码

哪个不是 0。

但是,记录了作为 XMLHttpRequest 对象的.status 属性的值的 0,尽管跟踪所有相关细节有点棘手。我们从https://xhr.spec.whatwg.org/#the-status-attribute 开始,记录.status 属性,它简单说明:

status 属性必须返回responsestatus

这听起来可能很空洞且重复,但实际上这里有信息!请记住,本文档在这里讨论的是 XMLHttpRequest.response 属性,而不是响应,因此这告诉我们 XHR 对象上的状态定义推迟到 Fetch 规范中响应状态的定义.

但是什么响应对象呢?如果我们实际上还没有收到回复怎么办? “响应”一词的内联链接将我们带到https://xhr.spec.whatwg.org/#response,它解释说:

XMLHttpRequest 具有关联的响应。除非另有说明,否则它是network error

所以我们得到的响应状态默认是网络错误。通过搜索在 XHR 规范中使用的短语 “set response to”,我们可以看到它被设置在五个地方:

查看Fetch standard,我们可以看到:

network errorresponse,其 status 始终为 0

因此,在 XHR 规范规定响应应设置为网络错误的任何情况下,我们都可以立即知道 XHR 对象的状态为 0。 (有趣的是,这包括正文的流被“错误”的情况,Fetch 规范告诉我们,这可能发生在解析正文的过程中收到状态 - 所以理论上我认为这是可能的将 XHR 对象的状态设置为 200,然后在接收主体时遇到内存不足错误或其他问题,因此将其状态更改回 0。)

我们还在 Fetch 标准中注意到,存在一些其他响应类型,它们的状态被定义为 0,它们的存在与跨域请求和同源策略有关:

不透明的过滤响应是filtered response,其...状态为0...

不透明重定向过滤响应是filtered response,其...状态为0...

(省略了有关这两种响应类型的其他各种详细信息)。

但除此之外,还有很多情况是 Fetch 算法(而不是我们已经看过的 XHR 规范)要求浏览器返回网络错误!事实上,“返回网络错误”这一短语在 Fetch 标准中出现了 40 次。我不会尝试在这里列出所有 40 个,但我注意到它们包括:

  • 请求的方案无法识别的情况(例如,尝试向 madeupscheme://foobar.com 发送请求)
  • 非常模糊的指令“如有疑问,请返回网络错误。”在处理 ftp:// 和 file:// URL 的算法中
  • 无限重定向:“如果请求的重定向计数为 20,则返回网络错误。”
  • 一堆与 CORS 相关的问题,例如“如果 httpRequest 的响应污染不是“cors”并且请求和响应返回的跨域资源策略检查被阻止,则返回网络错误。”
  • 连接失败:“如果连接失败,返回网络错误。”

换句话说:每当出现问题时其他除了从服务器获取真正的 HTTP 错误状态代码(如 500 或 400)之外,您最终会在 XHR 对象上获得状态属性 0 或在浏览器中获取响应对象。规范中列举的可能的具体原因数量众多。

最后:如果您出于某种原因对规范的历史感兴趣,请注意,此答案在 2020 年被完全重写,您可能对 previous revision of this answer 感兴趣,它解析了基本相同的结论旧的(并且更简单的)XHR W3 规范,在这些被更现代和更复杂的 WhatWG 规范取代之前,这个答案所指的。

【讨论】:

    【解决方案2】:

    在通过刷新页面或请求无法访问的 URL 获得响应之前取消 ajax 调用时出现状态 0。

    此状态未记录,但存在于来自 gadget.io 的 ajax 和 makeRequest 调用中。

    【讨论】:

    • 您好,有什么方法可以区分失败(“无网络”)和取消请求吗?
    • 此状态记录为 XmlHttpRequest 状态。当然它不是http状态,但它是记录在案的。 w3.org/TR/XMLHttpRequest/#the-status-attribute 更多详情请参阅 Mark Amery 回复。
    【解决方案3】:

    知道这是一篇旧帖子。但这些问题依然存在。

    以下是我对这个主题的一些发现,粗略的解释。

    根据 XMLHttpRequest 规范,“状态”0 表示三件事之一:

    • dns 名称解析失败(例如拔出网络插头时)

    • 服务器没有应答(也就是无法访问或无响应)

    • 请求因 CORS 问题而中止(中止由用户代理执行,并在 OPTIONS 飞行前失败后执行)。

    如果您想更进一步,请深入研究 XMLHttpRequest 的内部。建议阅读ready-state更新序列([0,1,2,3,4]为正常序列,[0,1,4]对应状态0,[0,1,2,4]表示无内容发送,这可能是一个错误或不是)。您可能还希望将侦听器附加到 xhr(onreadystatechange、onabort、onerror、ontimeout)以了解详细信息。

    来自规范 (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;
    

    【讨论】:

    • 您的列表中所有可能的原因都是正确的,但您的列表并不详尽。例如,您缺少超时、无限重定向循环以及my answer 中详述的其他原因。但是,指向新的 XHR 规范的指针很有用;我应该更新我的答案以引用它而不是旧的 W3 规范。
    【解决方案4】:

    来自文档http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute 表示一个请求在去任何地方之前被取消了

    【讨论】:

    • 这是列出的几个可能含义之一。
    【解决方案5】:

    从 iOS 9 开始,您需要在 info.plist 文件中添加“应用程序传输安全设置”并允许“允许任意加载”,然后再向非安全 HTTP Web 服务发出请求。我在我的一个应用中遇到了这个问题。

    【讨论】:

      【解决方案6】:

      是的,ajax 调用是如何中止的。原因可能如下。

      1. 在完成 ajax 请求之前,用户导航到其他页面。
      2. Ajax 请求超时。
      3. 服务器无法返回任何响应。

      【讨论】:

        猜你喜欢
        • 2019-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-10
        • 2017-09-25
        • 2019-11-05
        • 2015-01-12
        相关资源
        最近更新 更多