-1

When I run it in the console I should see the ajax object with readyState as 0 (which is right cause I aborted the ajax call) and after that I should of course see a 0 too cause I am just retrieving a property of the previous object. However Chrome is displaying in the console the number 4 instead of 0! This is unbelievable.

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();

Does anyone knows how to fix this problem in Chrome? I will report this bug to them but I would like someone here smarter than I to take a close look and tell me if this is really a bug.

--

IF ANYONE is smart read this:

It looks like nobody read my question.

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(); WHY in the first line of the console the object temp has readyState property set to 0 and in the second line of console temp.readyState shows 4? Both should be the same, despite any browser particular behaviour.

If an object has a property xxx set to 0 then object.xxx MUST be 0 not 4 as my example shows this bug.

amandanovaes
  • 694
  • 2
  • 7
  • 20
  • do you wanna know what is more unbelieable? but a setTimeout(...,1000) inside the onreadystatechange and it works perfectly. Have no idea why. – amandanovaes Mar 21 '14 at 19:58
  • erm, chrome is just too fast? lol – Populus Mar 21 '14 at 19:58
  • no chrome is not too fast cause I tried sending a large file with 10MB and even with a large file when I abort it return 4 to readyState. WHAT I cant believe is that the object in the console shows readyState setted with value 0 but when I just display that property with temp.readyState, right in the next line, it shows different, 4. Why? I have never seen it. – amandanovaes Mar 21 '14 at 19:59
  • ALso http://stackoverflow.com/questions/632774/what-do-the-different-readystates-in-xmlhttprequest-mean-and-how-can-i-use-them look at the accepted answer's comments. – Populus Mar 21 '14 at 20:01
  • @Populus they explain a little but it still does not explain why in the console the object shows readyState with the value 0 and in the console it shows the object.readyState with value 4 right in the next line of code? – amandanovaes Mar 21 '14 at 20:06
  • @amandanovaes umm - the chrome console is asynchronous. It doesn't show completely accurate state - use the debugger. – Benjamin Gruenbaum Mar 21 '14 at 20:07
  • because there isn't a set-in-stone standard for what the `readyState` should be after an abort. Some browsers will "reset" the entire `xmlhttprequest` object, hence the readyState of 0; while some others may consider it an error, which would have a `readyState` of 4 (most do this). Also your test is incorrect as the request is asynchronous, so depending on browser implementation and luck, the `abort` may or may not execute before the request completes, or if it has even started at all. – Populus Mar 21 '14 at 20:12
  • @Populus you are right but why does the object has the property set to 0 and the temp.readyState is set to 4? temp.readyState should read the readyState property of the object temp and both should be the same. – amandanovaes Mar 21 '14 at 20:17
  • The spec says step 6, set state to 4. Fire readystatechange. After that set state to 0, do not fire readystate change. – epascarello Mar 21 '14 at 20:31

3 Answers3

0

This actually happens in some other browsers too. When the XMLHttpRequest is aborted the readyState property changes to 4 before changing to 0 again, as the specification says it should.

That's why if you check for the onchangestate event, you may get a readyState value of 4, even if the request is aborted.

To detect if the request was aborted by the user you cold use this expression:

!xhr.getAllResponseHeaders();

Where xhr is the XMLHttpRequest object, and the expression will return true if the request was aborted by the user.

The truth is, browsers just have to (not really) follow what the specification says, so if it says "when the user aborts the readyState property should be 0", they just have to set it to 0 at the end of the process, and every implementation of a browser may have it's own kind of weird stuff goin on before actually doing what the specification says.

user3417400
  • 341
  • 2
  • 4
  • thank you Sir, but there is a problem in what you said: why in the console the object shows readyState with the value 0 and in the console it shows the object.readyState with value 4? – amandanovaes Mar 21 '14 at 20:03
0

If you want to see readyState zero [unset], you need to do it outside of the onreadystatechange handler and before open is triggered.

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

and the console will display

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

And now to make abort into account

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);

console output

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

It is doing exactly what the Spec says in the last steps

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.

In plain English, it says. Set the ready state to 4 and fire the onreadystatechange. After this it says set the ready state to zero and do not send a new onreadystatechange. That is why when you look at my last example it shows a 4 followed by a 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 

And now you confusion about the console

you said:

No it does not explain why in a=new Array("readyState"=>0); console.log(a) shows "readyState"=>0 BUT console.log(a["readyState"]); shows 4.

That is because console.log(a) is a reference to the object! The console does NOT show the value at the time it is recorded, it shows the value when you look at it. It is dynamically updated!

Simple demo in the browser shows what I am talking about.

enter image description here

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

epascarello
  • 204,599
  • 20
  • 195
  • 236
  • you are right but did you try console.log(temp) ? Check the last one, it should have the property readyState setted to 4 (as you showed in your example) but no, it has readyState setted to 0! Just change console.log(temp.readyState) in your code to console.log(temp) – amandanovaes Mar 21 '14 at 20:09
  • It even explicitly says so in the spec: "No readystatechange event is dispatched." – Benjamin Gruenbaum Mar 21 '14 at 20:10
  • @epascarello abort does trigger onreadystate! in my example in the uqestion it triggers. also specifications says it triggers too and it's reseted to 0. – amandanovaes Mar 21 '14 at 20:11
  • Sir look at http://www.w3.org/TR/XMLHttpRequest2/#the-abort-method . See the number 3 "Fire an event named readystatechange." So readystatechange is fired when aborted. – amandanovaes Mar 21 '14 at 20:12
  • It's 0 indeed but change console.log("orsc:", temp.readyState); to console.log(temp);console.log("orsc:", temp.readyState); and you will see that the object property readyState 0 but temp.readyState is 4 – amandanovaes Mar 21 '14 at 20:15
  • You are amazing. Thank you so much! It will certainly help other people! – amandanovaes Mar 21 '14 at 20:51
-1

It looks like nobody read my question.

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();

WHY in the first line of the console the object temp has readyState property set to 0 and in the second line of console temp.readyState shows 4? Both should be the same, despite any browser particular behaviour.

If an object has a property xxx set to 0 then object.xxx MUST be 0 not 4 as my example shows this bug.

amandanovaes
  • 694
  • 2
  • 7
  • 20