Adds CORS support (XDomainRequest) for IE7+ still through XMLHttpRequest
Fixes #106
I think onreadystatechange is more than enough for our case. Otherwise, full support requires both XDomainRequest and XMLHttpRequest <_<
@developit
Let us return to our muttons :)
this.status check here should be removed. we only care that readyState is 4.
I was still worried about your statement about removing status = 200 from this PR. So...
Today I've checked implementation of XHR, specially to check this moment because I was not sure about fully equivalent to load events for just readystate = 4 (I just don't remember this moment, and can't find any official documentation about this today).
However, seems my first thought that appeared from my example #106 (well, exactly from my mentioned task), was initially a correct thought.
So I'm not agree with you :)
I'll illustrate possible bug via Firefox:
We will initialize onreadystatechange via FireReadystatechangeEvent() method
- init -> adding for listeners -> then dispatching methods ->
basically the only readystatechange is a core event, while the others implementation just will be used when processing the main
Before final processing I'm also seeing decoding response and finally changing state and dispatching our additional events
there are many places that we will raise after, but mainly, this is what I'm talking about:
XMLHttpRequestMainThread::ChangeStateToDone()
{
...
if (mErrorLoad != ErrorType::eOK) {
DispatchProgressEvent(this, ProgressEventType::error, 0, -1);
} else {
DispatchProgressEvent(this, ProgressEventType::load,
mLoadTransferred, mLoadTotal);
}
when, for example:
void
XMLHttpRequestMainThread::CloseRequest()
{
mWaitingForOnStopRequest = false;
mErrorLoad = ErrorType::eTerminated;
if (mChannel) {
mChannel->Cancel(NS_BINDING_ABORTED);
}
when, for example:
void
XMLHttpRequestMainThread::TerminateOngoingFetch() {
if ((mState == XMLHttpRequest_Binding::OPENED && mFlagSend) ||
mState == XMLHttpRequest_Binding::HEADERS_RECEIVED ||
mState == XMLHttpRequest_Binding::LOADING) {
CloseRequest();
}
}
and so on ...
Thus! we will never have processing for onload events (javascript) when processing the same failed state for onreadystatechange (javascript)
That is, as I understand from this code, the onload event is equal to onreadystatechange only when
readyState === 4 && status !== 0
Or more probably(I've not inspected a lot), I'm seeing many places for changing status, like status from http channel via all overrided virtual methods
MOZ_MUST_USE NS_IMETHOD GetResponseStatus(uint32_t *aResponseStatus) = 0;
and other, but seems status === 200 (as it was initially from my example) is a correct way.
Unfortunately, I still can't find official documentation for compare logic onload vs onreadystatechange but from source code, it looks like this is it.
Please check this out, again.
I'll try also to prepare a common example later if needed (javascript of course) to reproduce this behavior.
I'm still here, and this is my explanation via javascript now:
let xhr = new XMLHttpRequest();
window.XMLHttpRequest.prototype.xD = function(evt)
{
console.log(evt, this.readyState, this.status);
}
xhr.onreadystatechange = function()
{
if(this.readyState !== 4) return;
xhr.xD('readystatechange()');
}
xhr.onload = () => xhr.xD('load()');
xhr.onabort = () => xhr.xD('abort()');
xhr.open('GET', 'https://api.github.com/users/3F/repos');
xhr.send();
// readystatechange() 4 200
// load() 4 200
setTimeout(() => xhr.abort(), 100);
// readystatechange() 4 0 <<<<<<<
// abort() 4 0
xhr.open('GET', 'https://api.github.com/users/3F/NULL');
xhr.send();
// readystatechange() 4 404
// load() 4 404
xhr.abort();
// readystatechange() 4 0 <<<<<<<
// abort() 4 0
So I'm thinking at least for non 0 state :p Or I need to inspect more via original implementation (C++ src see above). For chromium etc please check it yourself. I will not.
Any related official doc/RFC is really appreciated. Because it maybe just a bug of engines (I'm not sure because I have no info), like:
// The ChangeState call above calls onreadystatechange handlers which
// if they load a new url will cause XMLHttpRequestMainThread::Open to clear
// the abort state bit. If this occurs we're not uninitialized (bug 361773).
if (mFlagAborted) {
ChangeState(XMLHttpRequest_Binding::UNSENT, false); // IE seems to do it
}