From 0c80df21b66f4b147b6b55c27ad794be5802b411 Mon Sep 17 00:00:00 2001 From: Kristian Hellang Date: Fri, 27 Jun 2014 13:51:42 +0200 Subject: [PATCH] fix($http): should not read statusText on IE<10 when request is aborted Commit 1d2414c introduced a regression by retrieving the statusText of an aborted xhr request. This breaks IE9, which throws a c00c023f error when accessing properties of an aborted xhr request. The fix is similar to the one in commit 6f1050d. --- src/ng/httpBackend.js | 11 +++++++++-- test/ng/httpBackendSpec.js | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/ng/httpBackend.js b/src/ng/httpBackend.js index ba4585959..f285654b7 100644 --- a/src/ng/httpBackend.js +++ b/src/ng/httpBackend.js @@ -81,7 +81,8 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc // Safari respectively. if (xhr && xhr.readyState == 4) { var responseHeaders = null, - response = null; + response = null, + statusText = ''; if(status !== ABORTED) { responseHeaders = xhr.getAllResponseHeaders(); @@ -91,11 +92,17 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc response = ('response' in xhr) ? xhr.response : xhr.responseText; } + // Accessing statusText on an aborted xhr object will + // throw an 'c00c023f error' in IE9 and lower, don't touch it. + if (!(status === ABORTED && msie < 10)) { + statusText = xhr.statusText; + } + completeRequest(callback, status || xhr.status, response, responseHeaders, - xhr.statusText || ''); + statusText); } }; diff --git a/test/ng/httpBackendSpec.js b/test/ng/httpBackendSpec.js index 46cefea71..ed14a72dc 100644 --- a/test/ng/httpBackendSpec.js +++ b/test/ng/httpBackendSpec.js @@ -98,6 +98,25 @@ describe('$httpBackend', function() { expect(callback).toHaveBeenCalledOnce(); }); + it('should not touch xhr.statusText when request is aborted on IE9 or lower', function() { + callback.andCallFake(function(status, response, headers, statusText) { + expect(statusText).toBe((!msie || msie >= 10) ? 'OK' : ''); + }); + + $backend('GET', '/url', null, callback, {}, 2000); + xhr = MockXhr.$$lastInstance; + spyOn(xhr, 'abort'); + + fakeTimeout.flush(); + expect(xhr.abort).toHaveBeenCalledOnce(); + + xhr.status = 0; + xhr.readyState = 4; + xhr.statusText = 'OK'; + xhr.onreadystatechange(); + expect(callback).toHaveBeenCalledOnce(); + }); + it('should call completion function with empty string if not present', function() { callback.andCallFake(function(status, response, headers, statusText) { expect(statusText).toBe('');