javascript - XMLHttpRequest onreadystatechange 从未为 readyState 0 触发

标签 javascript ajax xmlhttprequest readystate onreadystatechange

我设置了常用的 XMLHttpRequest,到目前为止一切正常,我可以检索数据和 readyState 更改并执行各种操作。

有一点不会发生,那就是 readyState 在达到 0 时会触发 onreadystatechange() 函数。

现在我想知道...为什么?

我查看了 XMLHttpRequest MDN entry但是没有提到为什么当 readyState 达到 0 时不应触发 onreadystatechange。我也没有找到关于该主题的其他信息...

片段:

// Inside a class, this = class instance
this.socket = new XMLHttpRequest();

// For easy access of this class instance in onreadystatechange
var client = this;

// Write current readyState to console
this.socket.onreadystatechange = function ()
{
    // Adding this just to verify there are no errors in if block
    console.log("readyState: "+client.socket.readyState);

    if(client.socket.readyState === 0)
    {
        console.log("readyState is 0");
    }
    else
    {
        console.log("readyState is "+client.socket.readyState);
    }
}

当 XMLHttpRequest 套接字处理完请求后,XMLHttpRequest 实例的值将是 readyState===0,至少 Firefox 的 JS 控制台告诉我这一点。

在执行请求后,JS 控制台正确列出了 readyStates 1-4 的日志消息,但没有请求之前和之后的 readyState 0 的消息。

理论上,当readyState从4变回0时,是不是应该触发onreadystatechange()函数?在使用当前 FF 和 Safari 的 macOS 以及使用 IE11 的 Win 上检查了这一点,到处都是相同的行为,onreadystatechange() 永远不会为 readyState 0 触发。

XMLHttpRequest 是故意不这样做的,还是我做错了什么?感谢任何有用的输入。 :)

(请不要使用“使用 jQuery”评论或类似的评论,谢谢。)

更新:

事实证明,在成功或失败的请求完成后,readyState 永远保持在 4,在 FF、IE、Safari 中验证。

但是,如果正在进行的请求被中止,则 readyState 将从 > 0 返回到 0。所以 readystatechange 确实发生了,但是 onreadystatechange 没有被触发,在 FF 和 Safari 中验证了这一点。

更新 3:

根据XMLHttpRequest spec ,当 XHR 处于 readyState 3(接收)并中止时,XHR 应使用 onreadystatechange 事件将 readyState 设置为 4(完成),发出网络错误,然后使用 no 将 readyState 设置为 0(未发送) onreadystatechange 事件。

但是当我中止处于 readyState 3(接收)的 XHR 时,它会首先将 readyState 设置为 4(完成),并带有 onreadystatechange 事件和 HTTP 状态 200(OK),然后它会触发 onabort 和 onloadend 并重置 readyState到 0(未发送)...但在任何时候都不会触发 onerror 事件。

非常困惑。

最佳答案

In theory, when the readyState changes from 4 back to 0, shouldn't the onreadystatechange() function be triggered?

XHR 实例不可重用。 如果Firefox 的 XHR 对象将状态从 4 返回到 0(这对我来说不是,见下文),那是 Firefox 特有的东西,但它没有用,而且它不会触发无用的事件也是如此。

状态从 DONE (4) 到 UNSENT (0) 是没有意义的。请求不是未发送。 完成

在评论中回复你的笔记:

But after aborting, it returns back to 0 --- after it was already in readyState 3 and retrieving the file...

嗯,那会有所不同 — 从 3 到 0,而不是从 4 到 0。如果我在 Chrome 和 Firefox 中做同样的事情,我也会看到这一点。

The spec for XHR's abort说:

  1. 当您说 (readyState 3) 时中止时,readyState 应该不会变回 0;相反,它应该更改为 4,设置对网络错误的响应,并触发 readystatechange 事件。

  2. 如果在 readyState 为 4 时中止,它应该变回 0 — 但规范没有说它应该触发 readystatechange 事件(而它确实说其他时候状态会被各种算法改变)。

因此,在这种边缘情况下,Chrome 和 Firefox 似乎都没有严格遵守规范。

关于javascript - XMLHttpRequest onreadystatechange 从未为 readyState 0 触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45634459/

相关文章:

javascript - 如何将参数发送给不是常量的 JavaScript 方法?

javascript - Objection.js - 查询生成器不是使用插入方法的函数

javascript - 每 X 秒使用 mysql 数据更新 google java map

php - 自动更新 radio 检查

python - 如何在基于类的 View 中返回 JSON 响应,而不是 HTTP 响应

javascript - 跨域JSON请求?

javascript - google-chrome 扩展程序中的垃圾收集

javascript - 使用 AngularJS 发布请求

javascript - 当用户在 laravel 5 中关闭浏览器时如何在 Controller 中运行方法

jquery - XMLHttpRequest Origin null 不允许文件 :///to file:///(Serverless) 的 Access-Control-Allow-Origin