Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit a3172a2

Browse files
fix($httpBackend): only IE8 and below can't use script.onload for JSONP
IE8, IE9 and IE10 can use `script.onreadystate` so up till now we have been using this if the sniffer says we are on IE. But IE11 now does not support `script.onreadystate` and only supports the more standard `script.onload` and `script.onerror`. IE9 and IE10 do support `script.onload` and `script.onerror`. So now we only test whether we are on IE8 or earlier before using `script.onreadystate`. See http://pieisgood.org/test/script-link-events/ jQuery just uses all these handlers at once and hopes for the best, but since IE9 and IE10 support both sets of handlers, this could cause the handlers to be run more than once. jQuery also notes that there is a potential memory leak in IE unless we remove the handlers from the script object once they are run. So we are doing this too, now. Closes #4523 Closes #4527 Closes #4922
1 parent 84c408c commit a3172a2

File tree

2 files changed

+43
-6
lines changed

2 files changed

+43
-6
lines changed

src/ng/httpBackend.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -136,19 +136,24 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
136136
// - adds and immediately removes script elements from the document
137137
var script = rawDocument.createElement('script'),
138138
doneWrapper = function() {
139+
script.onreadystatechange = script.onload = script.onerror = null;
139140
rawDocument.body.removeChild(script);
140141
if (done) done();
141142
};
142143

143144
script.type = 'text/javascript';
144145
script.src = url;
145146

146-
if (msie) {
147+
if (msie && msie <= 8) {
147148
script.onreadystatechange = function() {
148-
if (/loaded|complete/.test(script.readyState)) doneWrapper();
149+
if (/loaded|complete/.test(script.readyState)) {
150+
doneWrapper();
151+
}
149152
};
150153
} else {
151-
script.onload = script.onerror = doneWrapper;
154+
script.onload = script.onerror = function() {
155+
doneWrapper();
156+
};
152157
}
153158

154159
rawDocument.body.appendChild(script);

test/ng/httpBackendSpec.js

+35-3
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ describe('$httpBackend', function() {
292292
script.readyState = 'complete';
293293
script.onreadystatechange();
294294
} else {
295-
script.onload()
295+
script.onload();
296296
}
297297

298298
expect(callback).toHaveBeenCalledOnce();
@@ -313,14 +313,46 @@ describe('$httpBackend', function() {
313313
script.readyState = 'complete';
314314
script.onreadystatechange();
315315
} else {
316-
script.onload()
316+
script.onload();
317317
}
318318

319319
expect(callbacks[callbackId]).toBeUndefined();
320320
expect(fakeDocument.body.removeChild).toHaveBeenCalledOnceWith(script);
321321
});
322322

323323

324+
if(msie<=8) {
325+
326+
it('should attach onreadystatechange handler to the script object', function() {
327+
$backend('JSONP', 'http://example.org/path?cb=JSON_CALLBACK', null, noop);
328+
329+
expect(fakeDocument.$$scripts[0].onreadystatechange).toEqual(jasmine.any(Function));
330+
331+
var script = fakeDocument.$$scripts[0];
332+
333+
script.readyState = 'complete';
334+
script.onreadystatechange();
335+
336+
expect(script.onreadystatechange).toBe(null);
337+
});
338+
339+
} else {
340+
341+
it('should attach onload and onerror handlers to the script object', function() {
342+
$backend('JSONP', 'http://example.org/path?cb=JSON_CALLBACK', null, noop);
343+
344+
expect(fakeDocument.$$scripts[0].onload).toEqual(jasmine.any(Function));
345+
expect(fakeDocument.$$scripts[0].onerror).toEqual(jasmine.any(Function));
346+
347+
var script = fakeDocument.$$scripts[0];
348+
script.onload();
349+
350+
expect(script.onload).toBe(null);
351+
expect(script.onerror).toBe(null);
352+
});
353+
354+
}
355+
324356
it('should call callback with status -2 when script fails to load', function() {
325357
callback.andCallFake(function(status, response) {
326358
expect(status).toBe(-2);
@@ -335,7 +367,7 @@ describe('$httpBackend', function() {
335367
script.readyState = 'complete';
336368
script.onreadystatechange();
337369
} else {
338-
script.onload()
370+
script.onload();
339371
}
340372
expect(callback).toHaveBeenCalledOnce();
341373
});

0 commit comments

Comments
 (0)