HTTP 状态码 0 是不是有任何意义?
Posted
技术标签:
【中文标题】HTTP 状态码 0 是不是有任何意义?【英文标题】: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 中推断出什么?它有普遍意义还是什么也没告诉我?
【问题讨论】:
请看这个问题,它涵盖了相同的主题:***.com/questions/872206/… 我相信这是最准确的答案:***.com/a/14507670/700206 另一篇相关帖子 - What does HTTP status code 0 mean 另见:What does it mean when an HTTP request returns status code 0? 【参考方案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
属性必须返回response 的status。
这听起来可能很空洞且重复,但实际上这里有信息!请记住,本文档在这里讨论的是 XMLHttpRequest
的 .response
属性,而不是响应,因此这告诉我们 XHR 对象上的状态定义推迟到 Fetch 规范中响应状态的定义.
但是什么响应对象呢?如果我们实际上还没有收到回复怎么办? “响应”一词的内联链接将我们带到https://xhr.spec.whatwg.org/#response,它解释说:
XMLHttpRequest
具有关联的响应。除非另有说明,否则它是network error。
所以我们得到的响应状态默认是网络错误。通过搜索在 XHR 规范中使用的短语 “set response to”,我们可以看到它被设置在五个地方:
网络错误,当:
theopen()
method 被调用,或者
响应的body 的stream 是errored(请参阅the send()
method 的文档中描述的算法)
timed out flag 已设置,导致request error steps 运行
the abort()
method 被调用,导致 request error steps 运行
对于使用 Fetch 发送请求产生的响应,通过 Fetch process response 任务(如果 XHR 请求是异步的)或 Fetch process response end-of-body 任务(如果 XHR 请求是同步的)。
查看Fetch standard,我们可以看到:
network error 是 response,其 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 调用是如何中止的。原因可能如下。
-
在完成 ajax 请求之前,用户导航到其他页面。
Ajax 请求超时。
服务器无法返回任何响应。
【讨论】:
以上是关于HTTP 状态码 0 是不是有任何意义?的主要内容,如果未能解决你的问题,请参考以下文章