HTTP请求返回状态码0是什么意思?


130

当JavaScript网络调用(例如fetch或XMLHttpRequest或任何其他类型的HTTP网络请求)失败且HTTP状态代码为0时,这是什么意思?

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

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

相同的代码在某些位置和系统上可以正常工作,但是在某些环境中,它会失败,并且状态码为0,并且没有提供responseText。

这是到Internet URL的典型HTTP POST。它不涉及file://,据我所知可能会返回0,表示在Firefox中成功。


可能是由于防火墙造成的吗?您的客户端在哪个操作系统上运行该应用程序?
shahkalpesh



我已经在Firefox有同样的问题,结果发现,广告拦截插件可防止包含单词网址的所有请求banner

Answers:


56

我相信错误代码表明响应为空,(甚至没有返回标头)。这表示已接受连接,然后正常关闭(TCP FIN)。造成这种情况的原因有很多,但是根据您的描述,某种形式的防火墙似乎是最有可能的罪魁祸首。


2
我认为您可能是对的。(尽管,正如@sleepycod指出的那样,在没有实际的 http状态代码的情况下,wininet.dll可能会返回一些状态代码。)
迈克·内尔森

1
这不一定是正确的。我遇到了同样的问题,但就我而言,从未发送过请求。其原因是,一个Firefox广告拦截阻止网址中包含的单词的请求banner

194

这里的许多答案都是错误的。 似乎人们找出了在特定情况下导致status == 0的原因,然后将其概括为答案。

实际上,将失败的XmlHttpRequest的status == 0视为未定义的错误。

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

从规范(fetch或XmlHttpRequest)中可以看到,此代码可能是由于甚至在联系服务器之前发生的错误的结果。

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

  1. 非法的跨源请求(请参阅CORS
  2. 防火墙阻止或过滤
  3. 该请求本身已在代码中被取消
  4. 一个已安装的浏览器扩展正在破坏一切

对于浏览器来说,为这些status == 0场景中的更多场景提供详细的错误报告可能会有所帮助。实际上,有时status == 0会伴随有用的控制台消息,但在其他消息中则没有其他信息。


4
Firefox插件NoScript可以取消对不受信任的主机的XHR请求。
Ivan Solntsev 2013年

5
+1,都是准确的,``某种错误发生''是实际的解释。对于那些对规范给出的可能原因的完整列表感兴趣的人,我已在stackoverflow.com/a/26451773/1709587上发布了细分列表。
Mark Amery 2014年

1
马克·阿默里(Mark Amery)详细介绍的引起我最大麻烦的案件是cors案件。如果错误导致响应通过cors验证失败,您将获得0状态而不是http状态,因为当cors验证失败时,无法访问响应。尝试检测正在维护的Web api并响应503时尤其令人沮丧。如果此api在维护过程中不遵守cors,则您将无法检测到503,您将只能得到0,这可能是由于其他原因导致的。东西。
弗雷德里克

我曾遇到过CORS问题:请考虑使用,http而不是https最初是否通过加载页面来进行加载http,反之亦然。如果您的网页是通过来访问的POSThttps那么另一个词http不会执行ajax的操作POSThttp如果您的网页是最初通过来访问的,则不会执行ajax的操作https
维克托·波纳马列夫

同步请求在0状态下引发了更有意义的异常:stackoverflow.com/a/49573256/1192811
McX

35

值得一看的是,取决于浏览器,基于jQuery的AJAX调用将使用HTTP状态代码0调用您的成功回调。我们发现状态代码“ 0”通常意味着用户之前会导航到另一个页面AJAX调用完成。

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


是的,由于该页面已获得10,000次浏览,因此人们可能会遇到很多问题。
mike nelson 2010年

还是我应该说25,000次观看?
mike nelson

3
它有很多价值:这正是我的自动化测试中错误的地方。非常感谢!
alexfernandez 2011年

提出支持不是因为这是“正确的”答案,而是我的情况。
Juan Mendes 2014年

确实确实会发生这种情况,但这不是您将看到错误代码== 0 的唯一原因。您不能假设用户正在浏览并因此过滤出此类错误消息。
2014年

14

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服务器上还是没有Web服务器的本地网页上进行请求?

如果您不在网络服务器上运行脚本,则 XMLHttpRequest status = 0和XMLHttpRequest statusText = unknown可以为您提供帮助。


感谢您的代码。不,这不是本地请求,它是从本地运行的vbscript对Internet上的Web服务器的请求。
麦克尼尔森

6

解决方法:我们最终要做的是

我们认为这与防火墙问题有关,因此我们想出了解决该问题的方法。如果有人遇到同样的问题,请执行以下操作:

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

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

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

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

希望这对有类似要求的人有所帮助。在这种情况下,它是在展会上用在笔记本电脑上的Flash游戏。我们永远都无法使用笔记本电脑,只能将其通过电子邮件发送给客户,因为这次贸易展览是在另一个国家进行的。


嗨,我正在调查生产中的客户正在发生的类似问题。您说的问题是由防火墙引起的。您是否还记得防火墙造成的影响是什么,或者防火墙为此做了什么?
Ibrahim Najjar

5

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

这可能是由于超时,XHR中止或防火墙对请求的踩踏而发生的。超时很常见,这意味着请求无法在指定的时间内执行。XHR Abortion的操作非常简单...实际上,您可以在XMLHttpRequest对象上调用.abort()来取消AJAX调用。(如果您不希望AJAX调用返回并尝试引用已销毁的对象,那么这对于单页应用程序来说是个好习惯。)如标记答案中所述,防火墙也可以取消请求并触发此请求0响应。

XHR Abort:使用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将在中止时为“错误”,在发生超时时为“超时”。

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

4

本页上的答案所详述,状态代码0表示由于某种原因请求失败,而javascript库将失败解释为状态代码0。

要对此进行测试,您可以执行以下任一操作:

1)使用此chrome扩展名,请求地将您的url从您的url https版本重定向到该http版本,因为这将导致混合的内容安全性错误,并最终生成状态代码0。这种方法的优点是您不需要您完全不必更改应用,只需使用此扩展名“重写”您的网址即可。

2)更改应用程序的代码,以选择使端点重定向到http您的url https版本而不是版本(反之亦然)。如果执行此操作,则请求将失败,状态码为0。


1
“使用此chrome扩展程序” — chrome扩展程序?在HTA应用程序中?
昆汀

4
肯定的一点!但是,大多数到达这里的人并不是来这里申请HTA的。他们正在搜索“ javascript http状态代码0”之类的信息,然后到达此处-因此,我认为,这个问题的HTA部分总体上意义不大,最终仍然有意义。
布莱德·帕克斯

2

以我为例,当我忘记将WWW放在我的域之前时,状态变为0。由于我所有的ajax请求都被硬编码为http:/WWW.mydomain.com,而加载的网页仅为http://mydomain.com,因此由于其域不同而成为安全问题。我最终在.htaccess文件中进行了重定向,以始终将www放在前面。


1

就我而言,这是因为AJAX调用由于同源策略而被浏览器阻止。这是最不值得期待的事情,因为我的所有HTML和脚本都从处提供127.0.0.1。如何认为它们有不同的来历?

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

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

我删除了<base>我并不需要的标签,现在它可以正常工作了!


1

我发现了状态== 0的新的且未记录的原因。这是我的经历:

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

它不是跨域,不是网络的,也不是由于取消的请求(通过代码或用户导航)引起的。开发者控制台或网络日志中没有任何内容。

我几乎找不到关于state()的文档(Mozilla未列出它,W3C列出了它),并且都没有提到“被拒绝”。

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


1

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

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

例如 :

NetworkError:发生网络错误。


0

万一其他人遇到此问题,由于发送了AJAX请求和正常表单请求,这给了我一些问题。我用以下行解决了它:

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

关键是返回false,这导致表单无法发送。您也可以从submitfunc()内部返回false,但是我发现明确地将其编写得更清楚。


1
防止默认值也适用于此。这是一个javascript函数,可防止浏览器在事件发生时执行默认行为,从而使您可以巧妙地覆盖/阻止本机功能... return false也会做同样的事情。
科里·丹尼尔森

0

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


0

如果您在本地PC上进行测试,它将无法正常工作。要测试Ajax示例,您需要将HTML文件放置在Web服务器上。


0

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

页面加载后,按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请求的协议设置为与页面请求的协议相同。

之前在Brad Parks的回答中提到了针对页面和js请求涉及不同协议的情况,但是我想这里介绍的诊断技术对于大多数用户来说更容易。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.