我设置了通常的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()函数吗?在macOS上使用当前的FF和Safari以及在使用IE11的Win上检查这一点,到处都是相同的行为,onreadystatechange()永远不会为readyState 0触发。
XMLHttpRequest是故意不按设计做的,还是我做错了什么?感谢任何有用的输入。 :)
(请不要“使用jQuery”评论或类似,thx。)
更新:
在成功或失败的请求完成后,在FF,IE,Safari中验证,readyState将永久保留为4。
但是,readyState将从>返回如果正在进行的请求被中止,则为0到0。所以一个readystatechange确实发生了,但onreadystatechange没有被触发,在FF和Safari中验证了这一点。
更新3 :
根据XMLHttpRequest spec,当XHR处于readyState 3(接收)并中止时,XHR应使用onreadystatechange事件将readyState设置为4(完成),发出网络错误,然后将readyState设置为0(不带否 onreadystatechange事件。
但是当我中止处于readyState 3(接收)的XHR时,它将首先使用onreadystatechange事件和HTTP状态200(OK)将readyState设置为4(完成),然后它将触发onabort和onloadend并重置readyState到0(未发送)......但是在任何时候都没有触发onerror事件。
非常混乱。
答案 0 :(得分:1)
理论上,当readyState从4变回0时,不应该触发onreadystatechange()函数吗?
XHR实例不可重用。 如果 Firefox的XHR对象将状态从4恢复为0 (它不适合我,请参见下文),这是Firefox特有的,但它没用,并且它也不会在它上面发出无用的事件。
状态从DONE
(4)转到UNSENT
(0)是没有意义的。请求未未发送。它已经完成了。
在评论中重新注明:
但是在中止之后,它返回0 ---它已经处于readyState 3并且检索文件...
啊,好吧,那会有所不同 - 从 3 到0,而不是从4到0.我也看到了,如果我在Chrome和Firefox中都这样做的话。
当您说(readyState
3)时中止,readyState
应该不更改回0;相反,它应该更改为4,将响应设置为网络错误,并触发readystatechange
事件。
如果在readyState
为4时中止,它应该更改回0 - 但规范不说它应该触发readystatechange
事件(而它确实说其他时候状态是由各种算法改变的。)
因此,似乎Chrome和Firefox都没有严格遵循此边缘情况下的规范。
答案 1 :(得分:-1)
0表示尚未发送请求的值。您无法发送请求,因此无法将事件从4更改为0。 就像你发了一封邮件然后等你发送邮件一样。这毫无意义。你只能等待其他事情发生(例如邮递员接受它,它到达,......)但很明显,如果你等待已经发生的事情,你将等待很长时间。
值状态描述
0已创建UNSENT客户端。 open()还没有被调用。
已打开1个已打开的open()。
已调用HEADERS_RECEIVED发送(),标题和状态为 可用。
3加载下载; responseText保存部分数据。
4 DONE操作完成。
<强>更新强>
在我寻找答案的过程中,我发现了XMLHttpRequest的这种实现方式。这表明中止功能不会发送任何事件。这可能是你无法抓住这个事件的原因,因为它根本就没有被解雇。
cXMLHttpRequest.prototype.abort = function() {
// Add method sniffer
if (cXMLHttpRequest.onabort) {
cXMLHttpRequest.onabort.apply(this, arguments);
}
// BUGFIX: Gecko - unnecessary DONE when aborting
if (this.readyState > cXMLHttpRequest.UNSENT) {
this._aborted = true;
}
this._object.abort();
// BUGFIX: IE - memory leak
fCleanTransport(this);
this.readyState = cXMLHttpRequest.UNSENT;
delete this._data;
/* if (this._async) {
* fQueue_remove(this);
* }
*/
};