Skip to content

Commit 96eefdf

Browse files
PatrickJSmhevery
authored andcommitted
fix(XHRConnection): use xhr status code
closes angular#2841 - [x] Tests
1 parent 7bf7ec6 commit 96eefdf

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

modules/angular2/src/http/backends/xhr_backend.ts

+15-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,21 @@ export class XHRConnection implements Connection {
3636
// TODO(jeffbcross): implement error listening/propagation
3737
this._xhr.open(requestMethodsMap.getMethod(ENUM_INDEX(req.method)), req.url);
3838
this._xhr.addEventListener('load', (_) => {
39-
var responseOptions = new ResponseOptions(
40-
{body: isPresent(this._xhr.response) ? this._xhr.response : this._xhr.responseText});
39+
// responseText is the old-school way of retrieving response (supported by IE8 & 9)
40+
// response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
41+
let response = isPresent(this._xhr.response) ? this._xhr.response : this._xhr.responseText;
42+
43+
// normalize IE9 bug (http://bugs.jquery.com/ticket/1450)
44+
let status = this._xhr.status === 1223 ? 204 : this._xhr.status;
45+
46+
// fix status code when it is 0 (0 status is undocumented).
47+
// Occurs when accessing file resources or on Android 4.1 stock browser
48+
// while retrieving files from application cache.
49+
if (status === 0) {
50+
status = response ? 200 : 0;
51+
}
52+
53+
var responseOptions = new ResponseOptions({body: response, status: status});
4154
if (isPresent(baseResponseOptions)) {
4255
responseOptions = baseResponseOptions.merge(responseOptions);
4356
}

modules/angular2/test/http/backends/xhr_backend_spec.ts

+31
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class MockBrowserXHR extends BrowserXhr {
3939
responseText: string;
4040
setRequestHeader: any;
4141
callbacks: Map<string, Function>;
42+
status: number;
4243
constructor() {
4344
super();
4445
var spy = new SpyObject();
@@ -49,6 +50,7 @@ class MockBrowserXHR extends BrowserXhr {
4950
this.callbacks = new Map();
5051
}
5152

53+
setStatusCode(status) { this.status = status; }
5254
addEventListener(type: string, cb: Function) { this.callbacks.set(type, cb); }
5355

5456
dispatchEvent(type: string) { this.callbacks.get(type)({}); }
@@ -135,6 +137,35 @@ export function main() {
135137
expect(setRequestHeaderSpy).toHaveBeenCalledWith('Content-Type', ['text/xml']);
136138
expect(setRequestHeaderSpy).toHaveBeenCalledWith('Breaking-Bad', ['<3']);
137139
});
140+
141+
it('should return the correct status code', inject([AsyncTestCompleter], async => {
142+
var statusCode = 418;
143+
var connection = new XHRConnection(sampleRequest, new MockBrowserXHR(),
144+
new ResponseOptions({status: statusCode}));
145+
146+
ObservableWrapper.subscribe(connection.response, res => {
147+
expect(res.status).toBe(statusCode);
148+
async.done();
149+
});
150+
151+
existingXHRs[0].setStatusCode(statusCode);
152+
existingXHRs[0].dispatchEvent('load');
153+
}));
154+
155+
it('should normalize IE\'s 1223 status code into 204', inject([AsyncTestCompleter], async => {
156+
var statusCode = 1223;
157+
var normalizedCode = 204;
158+
var connection = new XHRConnection(sampleRequest, new MockBrowserXHR(),
159+
new ResponseOptions({status: statusCode}));
160+
161+
ObservableWrapper.subscribe(connection.response, res => {
162+
expect(res.status).toBe(normalizedCode);
163+
async.done();
164+
});
165+
166+
existingXHRs[0].setStatusCode(statusCode);
167+
existingXHRs[0].dispatchEvent('load');
168+
}));
138169
});
139170
});
140171
}

0 commit comments

Comments
 (0)