HTTP状态码为0是否有任何含义?

106

当你在浏览器中的脚本中发起XMLHttpRequest时,如果浏览器设置为离线工作或者网络电缆被拔出,则请求将以错误状态和状态码=0完成。0未列入允许的HTTP状态码之中。

状态码0是什么意思?它在所有浏览器和HTTP客户端实用程序中意义相同吗?它是HTTP规范的一部分还是其他协议规范的一部分?似乎这意味着HTTP请求根本无法进行,也许是因为无法解析服务器地址。

适合向用户显示什么错误消息?“您可能未连接到互联网,网站遇到问题,或地址存在输入错误”?

我应该补充说明,在Firefox设置为“离线工作”时,我看到了这种行为,但在Microsoft Internet Explorer设置为“离线工作”时却没有看到。在IE中,用户会收到一个对话框,提供了在线选项。FireFox在返回错误前不会通知用户。

我之所以提出这个问题,是为了回应“显示更好的错误消息”的请求。Internet Explorer的做法很好。它告诉用户问题的原因,并为他们提供修复选项。为了在FireFox中提供等效的UX,我需要推断问题的原因并通知用户。因此,从状态0中我能推断出什么?它是否具有普遍意义或者根本无法提供任何信息?


请参考这个问题,它涵盖了相同的主题:https://dev59.com/GXNA5IYBdhLWcg3wrP2q - Scott Stafford
3
我相信这是最准确的答案:https://dev59.com/GXNA5IYBdhLWcg3wrP2q#14507670。 - whitneyland
另一个相关的帖子 - HTTP状态码0是什么意思 - RBT
6个回答

181

简短回答

它不是HTTP响应代码,但在WhatWG文档中被记录为XMLHttpRequest或Fetch响应的状态属性的有效值。

广义上来说,当没有“真正”的HTTP状态码报告和/或发送请求或接收响应时出现错误时,它是使用的默认值。可能出现这种情况的情形包括但不限于:

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

详细回答

首先,重申一下:0不是HTTP状态码。在RFC 7231 Section 6.1中有一个完整的列表,其中不包括0,而第6节的介绍清楚地说明了:
状态码元素是一个三位数字代码
其中0不是。
然而,XMLHttpRequest对象的.status属性的值为0是有文档记录的,尽管跟踪所有相关细节有点棘手。我们从https://xhr.spec.whatwg.org/#the-status-attribute开始记录.status属性,它只是简单地声明: status属性必须返回响应状态
这可能听起来空洞和自指,但实际上这里有信息!请记住,此文档在谈论 XMLHttpRequest.response 属性,而不是响应,因此这告诉我们 XHR 对象上状态的定义被推迟到 Fetch 规范中响应状态的定义。
但是哪个响应对象?如果我们还没有收到响应怎么办?单词“响应”上的内联链接将带我们到https://xhr.spec.whatwg.org/#response,其中解释了:

XMLHttpRequest 有一个关联的响应。除非另有说明,否则它是 网络错误

所以我们获取状态的响应默认为网络错误。通过搜索 XHR 规范中使用短语“设置响应”的所有地方,我们可以看到它在五个位置设置:

查看获取标准,我们可以看到:

网络错误是一种响应,其状态始终为0

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

我们还在Fetch标准中注意到存在另外几种响应类型,其状态被定义为0,其存在与跨域请求和同源策略有关:
不透明过滤响应是一个过滤响应,其状态为0...
不透明重定向过滤响应是一个过滤响应,其状态为0...
(省略了这两种响应类型的其他细节)。
但除此之外,还有许多情况下,Fetch算法(而非我们已经查看过的XHR规范)要求浏览器返回网络错误!事实上,在Fetch标准中“返回网络错误”的短语出现了40次。我不会在此列出所有40个条目,但需要注意的是:它们包括:
  • 请求方案无法识别的情况(例如尝试将请求发送到madeupscheme:// foobar.com)
  • 处理ftp://和file:// URL算法中的模棱两可的指令“当有疑问时,请返回网络错误。”
  • 无限重定向:“如果请求的重定向计数为20,则返回网络错误。”
  • 一堆与CORS相关的问题,例如“如果httpRequest的响应污染不是“cors”,并且请求和响应的跨源资源策略检查返回blocked,则返回网络错误。”
  • 连接失败:“如果connection失败,则返回网络错误。”

换句话说:每当出现问题,而不是从服务器获得真正的HTTP错误状态代码(如500或400),您在浏览器中的XHR对象或Fetch响应对象上会得到状态属性0。规范中列出了大量可能的具体原因。

最后提醒:如果你对规范的历史感兴趣,注意这个答案已于2020年完全重写。你可能会对此答案的先前版本感兴趣,它从旧版(更为简单的)XHR W3规范中解析出基本相同的结论,而这些规范已被更现代、更复杂的WhatWG规范所取代。


56

当刷新页面或请求无法到达的URL时,在获取响应之前取消ajax调用会出现状态0。

这个状态在ajax和gadget.io的makeRequest调用中存在,但没有文档记录。


4
你好,有没有办法区分请求失败(“无网络”)和被取消的请求? - Ankur
2
这个状态被记录为XmlHttpRequest状态。当然它不是一个http状态,但已经被记录。请参考http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute中的Mark Amery反应以获取更多细节。 - Frédéric

6

虽然这是一篇旧帖子,但这些问题仍然存在。

以下是我对该主题的一些发现,概述如下:

"状态" 0 代表以下三种情况之一,根据XMLHttpRequest规范:

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

  • 服务器没有回答(也称为不可达或未响应)

  • 请求因CORS问题而被中止(中止由用户代理执行,并且遵循失败的OPTIONS预检查)。

如果您想深入了解XHR,请深入了解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;

1
你列出的所有可能原因都是正确的,但是你的列表并不全面。例如,你遗漏了超时、无限重定向循环和其他在我的回答中详细说明的原因。然而,指向新的活动XHR规范的指针是有用的;我应该更新我的答案来引用它,而不是旧的W3规范。 - Mark Amery

5

4
这是列出的几种可能含义之一。 - Mark Amery

0

自从iOS 9以来,您需要在info.plist文件中添加“App Transport Security Settings”并允许“Allow Arbitrary Loads”,然后才能向非安全的HTTP Web服务发出请求。我在我的一个应用程序中遇到了这个问题。


-1

是的,某种程度上Ajax调用被中止了。可能的原因如下:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接