与ajax的严重和简单的bug

时间:2014-03-21 19:44:05

标签: javascript ajax

当我在控制台中运行它时,我应该看到readyState为0的ajax对象(这是正确的,因为我中止了ajax调用),之后我当然应该看到0也因为我只是检索一个属性上一个对象。但是,Chrome在控制台中显示的是数字4而不是0!这真是难以置信。

http://jsfiddle.net/8yCfn/1/

temp = new XMLHttpRequest();

temp.open("POST","http://jsfiddle.net/",true);

temp.onreadystatechange = function() {

    console.log(temp);
    console.log(temp.readyState);

};

temp.send(null);

temp.abort();

有谁知道如何在Chrome中解决此问题?我会向他们报告这个错误,但我希望有人比我更聪明,仔细看看并告诉我这是不是真的是一个错误。

-

如果有人聪明,请阅读:

看起来好像没有人读我的问题。

temp = new XMLHttpRequest();

temp.open( “POST”, “http://jsfiddle.net/”,TRUE);

temp.onreadystatechange = function(){

console.log(temp);
console.log(temp.readyState);

};

temp.send(空);

temp.abort(); 为什么在控制台的第一行中,对象temp的readyState属性设置为0,而控制台的第二行temp.readyState显示为4?尽管有任何浏览器特定的行为,两者都应该是相同的。

如果一个对象的属性xxx设置为0,那么object.xxx必须是0而不是4,因为我的例子显示了这个bug。

3 个答案:

答案 0 :(得分:0)

这实际上也发生在其他一些浏览器中。当XMLHttpRequest被中止时,readyState属性在再次变为0之前变为4,正如规范所说的那样。

这就是为什么如果你检查onchangestate事件,你可能会得到readyState值为4,即使请求被中止。

要检测用户是否中止请求,请使用以下表达式:

!xhr.getAllResponseHeaders();

其中xhr是XMLHttpRequest对象,如果请求被用户中止,表达式将返回true。

事实是,浏览器必须(不是真的)遵循规范所说的内容,因此如果它说'#34;当用户中止readyState属性应为0"时,他们只需将其设置为在流程结束时为0,浏览器的每个实现都可能让它在实际执行规范所说的内容之前拥有它自己的一些奇怪的东西。

答案 1 :(得分:0)

如果你想看到readyState为零[unset],你需要在onreadystatechange处理程序之外和触发open之前这样做。

temp = new XMLHttpRequest();
temp.onreadystatechange = function() {
    console.log(temp.readyState);
};
console.log(temp.readyState);
temp.open("POST",window.location.href,true);
temp.send(null);

,控制台将显示

0 
1 
2 
3 
XHR finished loading: "http://fiddle.jshell.net/_display/".
4

现在要考虑中止

temp = new XMLHttpRequest();
temp.onreadystatechange = function() {
    console.log("orsc:", temp.readyState);
};
console.log("Before Open: ", temp.readyState);
temp.open("POST",window.location.href,true);
temp.send(null);
temp.abort();
console.log("After abort: ", temp.readyState);

控制台输出

Before Open: 0 
orsc: 1 
orsc: 4 
After abort: 0 

它正在完成Spec在最后几步中所说的内容

6. If the state is UNSENT, OPENED with the send() flag being unset, or DONE go to the next step.
   Otherwise run these substeps:
        Change the state to DONE.   <---- Set to 4
        Unset the send() flag.
        Fire an event named readystatechange.    <---- Fire onreadystate change
        ...
7. Change the state to UNSENT.      <---- Set to 0
    No readystatechange event is dispatched.

用简单的英语说。将就绪状态设置为4并触发onreadystatechange。在此之后,它表示将就绪状态设置为零,并且不发送新的onreadystatechange。这就是为什么当你看我的最后一个例子时,它会显示一个4后跟一个0.

Before Open: 0 
orsc: 1 
orsc: 4          <--Abort step 6 - set to done, fire readystatechange
After abort: 0   <--Abort step 7 - set to zero, don't fire readystatechange 

现在你对控制台感到困惑

你说:

  

不能解释为什么在a = new Array(&#34; readyState&#34; =&gt; 0); console.log(a)显示&#34; readyState&#34; =&gt; 0但是console.log(a [&#34; readyState&#34;]);显示4。

这是因为console.log(a)是对象的引用!控制台在记录时不显示值,它会在您查看时显示值。它是动态更新的!

浏览器中的简单演示显示了我在说什么。

enter image description here

JSFiddle:http://jsfiddle.net/4RDh3/

答案 2 :(得分:-1)

看起来好像没有人读我的问题。

temp = new XMLHttpRequest();

temp.open("POST","http://jsfiddle.net/",true);

temp.onreadystatechange = function() {

    console.log(temp);
    console.log(temp.readyState);

};

temp.send(null);

temp.abort();

为什么在控制台的第一行中,对象temp的readyState属性设置为0,而控制台的第二行temp.readyState显示为4?尽管有任何浏览器特定的行为,两者都应该是相同的。

如果一个对象的属性xxx设置为0,那么object.xxx必须是0而不是4,因为我的例子显示了这个bug。

相关问题