It's just a matter of speed.
You need to use the .onreadystatechange function when you start an asynchronous XMLHTTP request, that's what the third parameter of the .open method means: asynchronous or not. When the .send() method is called, the XMLHTTP starts in another thread and will asynchronously process the request. Meanwhile, your script will continue as well. That means that, after the call to .send(), the script will try to assign the .onreadystatechange function. If the download is still busy, it will work. However, if the download is already done
after you assign the .onreadystatechange function, XMLHTTP won't call your function any more, since it has already completed.
When you assign the .onreadystatechange function
before you call .send(), you can be assured that the process will find your .onreadystatechange function.