当 HTTP 请求返回状态代码0时意味着什么?

当 JavaScript 网络调用,如 get 或 XMLHttpRequest,或任何其他类型的 HTTP 网络请求,以0为 HTTP状态码失败时,这意味着什么?

这似乎不是一个有效的 HTTP状态码,因为其他代码在 HTTP 规范中都是三位数。

我试着完全拔掉网络作为测试。这可能是不相关的,但导致状态代码17003(IIRC) ,粗略搜索表明“ DNS 服务器查找失败”。

同样的代码在某些位置和系统上可以很好地工作,但是在某些环境中,它失败了,状态代码为0,而且没有提供 response。

这是对 Internet URL 的典型 HTTP POST。它不涉及 file://,我知道它可能返回0表示 Firefox 成功。

351873 次浏览

wininet.dll返回下面列出的标准和非标准状态代码。

401 - Unauthorized file
403 - Forbidden file
404 - File Not Found
500 - some inclusion or functions may missed
200 - Completed


12002 - Server timeout
12029,12030, 12031 - dropped connections (either web server or DB server)
12152 - Connection closed by server.
13030 - StatusText properties are unavailable, and a query attempt throws an exception

对于状态代码“零”,您是否尝试在一个本地网页上执行请求,该网页运行在一个网络服务器上或没有一个网络服务器?

如果您没有在 Web 服务器上运行脚本,XMLHttpRequest status = 0和 XMLHttpRequest statusText = known 可以帮助您。

我相信错误代码表明响应是空的(因为甚至没有返回头)。这意味着连接被接受,然后优雅地关闭(TCP FIN)。 有很多因素可能导致这种情况,但根据你的描述,某种形式的防火墙似乎是最有可能的罪魁祸首。

变通方案: 我们最后做了什么

我们认为这与防火墙问题有关,所以我们想出了一个解决办法。如果有人有同样的问题,我们会这么做:

  1. 我们仍然像以前一样使用 HTA 将数据写入本地硬盘上的文本文件。

  2. 当用户单击“发送数据回服务器”时,HTA 读入数据并写出一个 HTML 页面,其中包含作为 XML 数据岛的数据(实际上使用 SCRIPT LANGUAGE = XML 脚本块)。

  3. HTA 在浏览器中启动到 HTML 页面的链接。

  4. HTML 页面现在包含将数据发送到服务器的 javascript (使用 Microsoft.XMLHTTP)。

希望这对任何有类似需求的人都有帮助。在这种情况下,它是一个 Flash 游戏用于笔记本电脑在贸易展览会。我们从来没有接触过这台笔记本电脑,只能通过电子邮件发送给客户,因为这个贸易展在另一个国家举行。

不管怎样,根据浏览器的不同,基于 jQuery 的 AJAX 调用将调用您的成功回调,HTTP状态码为0。我们发现状态码为“0”通常意味着用户在 AJAX 调用完成之前导航到另一个页面。

与您使用的技术栈不同,但希望对某些人有用。

如果其他任何人遇到这个问题,那么由于 AJAX 请求和正在发送的普通表单请求,这会给我带来问题。我用下面这句话解决了这个问题:

<form onsubmit="submitfunc(); return false;">

这里的键是 return false,它会导致表单不发送。您也可以从 submitfunc ()内部返回 false,但是我发现显式地编写它会更清楚。

HTTP 响应代码为0表示取消了 AJAX 请求。

这可能发生在超时、 XHR 流产或防火墙对请求的践踏。超时是常见的,它意味着请求未能在指定时间内执行。一个 XHR 堕胎是非常简单的做... 你实际上可以调用。对 XMLHttpRequest 对象执行 abort ()以取消 AJAX 调用。(如果您不希望 AJAX 调用返回并试图引用已经销毁的对象,那么对于单页应用程序来说,这是一个很好的实践。)正如标记答案中提到的,防火墙也能够取消请求并触发这个0响应。

XHR 中止: 使用 jQuery 中止 Ajax 请求

var xhr = $.ajax({
type: "POST",
url: "some.php",
data: "name=John&location=Boston",
success: function(msg){
alert( "Data Saved: " + msg );
}
});


//kill the request
xhr.abort()

值得注意的是,运行。XHR 对象上的 abort ()方法也会触发错误回调。如果您正在进行任何类型的错误处理来解析这些对象,您会很快注意到一个中止的 XHR 和一个超时的 XHR 是相同的,但是使用 jQuery 时,传递给错误回调的 textStatus 在中止时将是“中止”,并且在超时时发生“超时”。如果您正在使用 Zepto (非常类似于 jQuery) ,则 errorType 在中止时为“ error”,在超时时为“ timeout”。

jQuery: error(jqXHR, textStatus, errorThrown);
Zepto:  error(xhr, errorType, error);

这里的许多答案都是错误的。似乎人们在他们的特殊情况下找出了引起 status = = 0的原因,然后将其归纳为答案。

实际上,对于失败的 XmlHttpRequest,status = = 0应该被认为是一个未定义的错误。

实际的 W3C 规范在这里定义了返回零的条件: Https://fetch.spec.whatwg.org/#concept-network-error

正如您可以从规范(get 或 XmlHttpRequest)中看到的那样,这段代码可能是一个错误的结果,这个错误甚至在与服务器联系之前就已经发生了。

产生这种状态代码的一些常见情况反映在其他答案中,但可能是以下问题中的任何一个:

  1. 非法交叉原产地要求(见 CORS)
  2. 防火墙阻塞或过滤
  3. 请求本身在代码中被取消
  4. 安装的浏览器扩展程序把事情搞砸了

如果浏览器能够为更多的 status = = 0场景提供详细的错误报告,那将会很有帮助。实际上,有时 status = = 0会伴随有用的控制台消息,但是在其他情况下没有其他信息。

在我的案例中,这是因为浏览器因为 同一原产地政策而阻塞了 AJAX 调用。这是最意想不到的事情,因为我所有的 HTML 和脚本都是从 127.0.0.1提供的。它们怎么能被认为有不同的起源呢?

无论如何,根本原因是一个看起来无辜的 <base>标签:

<base href='<%=request.getScheme()%>://<%=request.getServerName() + ":" + request.getServerPort() + request.getContextPath()%>/'/>

我删除了 <base>标签,这是我不需要的方式,现在它的工作正常!

在我的情况下,当我忘记把 WWW 放在我的域名前面时,状态变为0。因为我所有的 ajax 请求都是硬编码的 http:/www.mydomain.com ,加载的网页只是 http://mydomain.com,所以它成了一个安全问题,因为它是一个不同的域。我最后在我的。Htaccess 文件总是把 www 放在前面。

应该注意的是,超过 nginx 的 client_max_body_size指令的 ajax 文件上传将返回此错误代码。

如详细的 在这一页上的这个答案所示,状态码为0意味着由于某种原因请求失败,而 javascript 库将失败解释为状态码为0。

要测试这一点,您可以执行以下任一操作:

1)使用这个 chrome 扩展,当然重定向您的网址从您的网址的 https版本到 http版本,因为这将导致混合内容安全性错误,并最终产生一个0的状态代码。这种方法的优点是你不必改变你的应用程序,你可以简单地使用这个扩展“重写”你的网址。

2)更改应用程序的代码,使端点可选地重定向到 URL 的 http版本,而不是 https版本(反之亦然)。如果这样做,请求将失败,状态代码为0。

我发现了 status = = 0的一个新的、没有文档记录的原因:

XMLHttpRequest.status === 0
XMLHttpRequest.readyState === 0
XMLHttpRequest.responseText === ''
XMLHttpRequest.state() === 'rejected'

它不是跨原点、网络或由于取消请求(通过代码或用户导航)。开发人员控制台或网络日志中没有。

我能找到的关于 state ()的文档非常少(Mozilla 没有列出它,W3C 列出了) ,而且没有一个提到“拒绝”。

原来是我的 广告拦截器(Firefox 上的 uBlock Origin)。

除了 Lee 的回答之外,通过切换到 同步请求,您可以找到更多关于真正原因的信息,因为您还会得到一个异常:

function request(url) {
var request = new XMLHttpRequest();
try {
request.open('GET', url, false);
request.send(null);
} catch (e) {
console.log(url + ': ' + e);
}
}

例如:

网络错误: 发生网络错误。

如果你是在本地电脑上测试,它不会工作。要测试 Ajax 示例,您需要将 HTML 文件放在 Web 服务器上。

在我的例子中,错误发生在使用 HTTP 协议请求的页面中,页面中包含一个试图发出 HTTPS 请求的 Javascript。反之亦然。

页面加载后,按 F12(或 Ctrl + U)并查看页面的 HTML 代码。如果您在代码中看到类似的内容:

<!-- javascript request inside the page -->
<script>
var ajaxurl = "https://example.com/wp-admin/admin-ajax.php";
(...)
</script>

你的页面是这样被要求的:

Http://example.com/example-page/2019/09/13/my-post/#elf_l1_lw

你肯定会面对这个错误。

要解决这个问题,需要将 Javascript 请求的协议设置为等同于页面请求的协议。

对于页面和 js 请求,这种涉及不同协议的情况之前在 布拉德 · 帕克斯的答案中提到过,但是,我想这里提到的诊断技术对于大多数用户来说更容易。