fix($browser.xhr): fix IE6, IE7 bug - sync xhr when serving from cache

IE6, IE7 is sync when serving content from cache.
We want consistent api, so we have to use setTimeout to make it async.
This commit is contained in:
Vojta Jina 2011-08-18 23:43:25 +02:00 committed by Igor Minar
parent e9b57f9df8
commit 3ae3ccf3da
2 changed files with 49 additions and 7 deletions

View file

@ -73,6 +73,11 @@ function Browser(window, document, body, XHR, $log, $sniffer) {
}
}
// normalize IE bug (http://bugs.jquery.com/ticket/1450)
function fixStatus(status) {
return status == 1223 ? 204 : status;
}
/**
* @ngdoc method
* @name angular.module.ng.$browser#xhr
@ -120,14 +125,22 @@ function Browser(window, document, body, XHR, $log, $sniffer) {
forEach(headers, function(value, key) {
if (value) xhr.setRequestHeader(key, value);
});
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// normalize IE bug (http://bugs.jquery.com/ticket/1450)
var status = xhr.status == 1223 ? 204 : xhr.status;
completeOutstandingRequest(callback, status, xhr.responseText);
}
};
xhr.send(post || '');
// IE6, IE7 bug - does sync when serving from cache
if (xhr.readyState == 4) {
setTimeout(function() {
completeOutstandingRequest(callback, fixStatus(xhr.status), xhr.responseText);
}, 0);
} else {
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
completeOutstandingRequest(callback, fixStatus(xhr.status), xhr.responseText);
}
};
}
return xhr;
}
};

View file

@ -227,6 +227,35 @@ describe('browser', function() {
it('should return raw xhr object', function() {
expect(browser.xhr('GET', '/url', null, noop)).toBe(xhr);
});
it('should be async even if xhr.send() is sync', function() {
// IE6, IE7 is sync when serving from cache
var xhr;
function FakeXhr() {
xhr = this;
this.open = this.setRequestHeader = noop;
this.send = function() {
this.status = 200;
this.responseText = 'response';
this.readyState = 4;
};
}
var callback = jasmine.createSpy('done').andCallFake(function(status, response) {
expect(status).toBe(200);
expect(response).toBe('response');
});
browser = new Browser(fakeWindow, jqLite(window.document), null, FakeXhr, null);
browser.xhr('GET', '/url', null, callback);
expect(callback).not.toHaveBeenCalled();
fakeWindow.setTimeout.flush();
expect(callback).toHaveBeenCalledOnce();
(xhr.onreadystatechange || noop)();
expect(callback).toHaveBeenCalledOnce();
});
});
describe('defer', function() {