Skip to content

Commit c882b26

Browse files
author
Gonzalo Ruiz de Villa
committed
fix(httpBackend): should not read response data when request is aborted
When a request is aborted, it makes no sense to read the response headers or text. Also in IE9, trying to read data (either response headers or text) from an aborted request throws an Error c00c023f. Fixes angular#4913
1 parent dfe6400 commit c882b26

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

src/ng/httpBackend.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,19 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
6969
// always async
7070
xhr.onreadystatechange = function() {
7171
if (xhr.readyState == 4) {
72-
var responseHeaders = xhr.getAllResponseHeaders();
72+
var responseHeaders = null,
73+
response = null;
74+
75+
if(!xhr.aborted) {
76+
responseHeaders = xhr.getAllResponseHeaders();
77+
response = xhr.responseType ? xhr.response : xhr.responseText;
78+
}
7379

7480
// responseText is the old-school way of retrieving response (supported by IE8 & 9)
7581
// response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
7682
completeRequest(callback,
7783
status || xhr.status,
78-
(xhr.responseType ? xhr.response : xhr.responseText),
84+
response,
7985
responseHeaders);
8086
}
8187
};
@@ -101,7 +107,7 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
101107
function timeoutRequest() {
102108
status = -1;
103109
jsonpDone && jsonpDone();
104-
xhr && xhr.abort();
110+
xhr && (xhr.aborted = true) && xhr.abort();
105111
}
106112

107113
function completeRequest(callback, status, response, headersString) {

test/ng/httpBackendSpec.js

+19
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,25 @@ describe('$httpBackend', function() {
118118
});
119119
});
120120

121+
it('should not try to read response data when request is aborted', function() {
122+
callback.andCallFake(function(status, response, headers) {
123+
expect(status).toBe(-1);
124+
expect(response).toBe(null);
125+
expect(headers).toBe(null);
126+
});
127+
$backend('GET', '/url', null, callback, {}, 2000);
128+
xhr = MockXhr.$$lastInstance;
129+
spyOn(xhr, 'abort');
130+
131+
fakeTimeout.flush();
132+
expect(xhr.abort).toHaveBeenCalledOnce();
133+
134+
xhr.status = 0;
135+
xhr.readyState = 4;
136+
xhr.onreadystatechange();
137+
expect(callback).toHaveBeenCalledOnce();
138+
});
139+
121140
it('should abort request on timeout', function() {
122141
callback.andCallFake(function(status, response) {
123142
expect(status).toBe(-1);

0 commit comments

Comments
 (0)