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

Commit 05e2c31

Browse files
Di PengIgorMinar
Di Peng
authored andcommitted
feat($browser): JSONP error handling
since we don't know if the error was due to a client error (4xx) or server error (5xx), we leave the status code as undefined.
1 parent 718ebf1 commit 05e2c31

File tree

2 files changed

+93
-23
lines changed

2 files changed

+93
-23
lines changed

src/Browser.js

+21-5
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,19 @@ function Browser(window, document, body, XHR, $log) {
100100
outstandingRequestCount ++;
101101
if (lowercase(method) == 'json') {
102102
var callbackId = ("angular_" + Math.random() + '_' + (idCounter++)).replace(/\d\./, '');
103-
var script = self.addJs(url.replace('JSON_CALLBACK', callbackId));
104-
window[callbackId] = function(data){
103+
window[callbackId] = function(data) {
104+
window[callbackId].data = data;
105+
};
106+
107+
var script = self.addJs(url.replace('JSON_CALLBACK', callbackId), null, function() {
108+
if (window[callbackId].data) {
109+
completeOutstandingRequest(callback, 200, window[callbackId].data);
110+
} else {
111+
completeOutstandingRequest(callback);
112+
}
105113
delete window[callbackId];
106114
body[0].removeChild(script);
107-
completeOutstandingRequest(callback, 200, data);
108-
};
115+
});
109116
} else {
110117
var xhr = new XHR();
111118
xhr.open(method, url, true);
@@ -452,7 +459,7 @@ function Browser(window, document, body, XHR, $log) {
452459
* @description
453460
* Adds a script tag to the head.
454461
*/
455-
self.addJs = function(url, domId) {
462+
self.addJs = function(url, domId, done) {
456463
// we can't use jQuery/jqLite here because jQuery does crazy shit with script elements, e.g.:
457464
// - fetches local scripts via XHR and evals them
458465
// - adds and immediately removes script elements from the document
@@ -465,6 +472,15 @@ function Browser(window, document, body, XHR, $log) {
465472
script.type = 'text/javascript';
466473
script.src = url;
467474
if (domId) script.id = domId;
475+
476+
if (msie) {
477+
script.onreadystatechange = function() {
478+
/loaded|complete/.test(script.readyState) && done && done();
479+
}
480+
} else {
481+
if (done) script.onload = script.onerror = done;
482+
}
483+
468484
body[0].appendChild(script);
469485

470486
return script;

test/BrowserSpecs.js

+72-18
Original file line numberDiff line numberDiff line change
@@ -87,27 +87,81 @@ describe('browser', function(){
8787

8888
describe('xhr', function(){
8989
describe('JSON', function(){
90-
it('should add script tag for request', function() {
91-
var callback = jasmine.createSpy('callback');
92-
var log = "";
93-
browser.xhr('JSON', 'http://example.org/path?cb=JSON_CALLBACK', null, function(code, data){
94-
log += code + ':' + data + ';';
95-
});
96-
browser.notifyWhenNoOutstandingRequests(callback);
97-
expect(callback).not.toHaveBeenCalled();
98-
expect(scripts.length).toEqual(1);
99-
var script = scripts[0];
100-
var url = script.src.split('?cb=');
101-
expect(url[0]).toEqual('http://example.org/path');
102-
expect(typeof fakeWindow[url[1]]).toEqual($function);
103-
fakeWindow[url[1]]('data');
104-
expect(callback).toHaveBeenCalled();
105-
expect(log).toEqual('200:data;');
106-
expect(scripts).toEqual(removedScripts);
107-
expect(fakeWindow[url[1]]).toBeUndefined();
90+
var log;
91+
92+
function callback(code, data) {
93+
log += code + ':' + data + ';';
94+
}
95+
96+
beforeEach(function() {
97+
log = "";
10898
});
99+
100+
101+
// We don't have unit tests for IE because script.readyState is readOnly.
102+
// Instead we run e2e tests on all browsers - see e2e for $xhr.
103+
if (!msie) {
104+
105+
it('should add script tag for JSONP request', function() {
106+
var notify = jasmine.createSpy('notify');
107+
browser.xhr('JSON', 'http://example.org/path?cb=JSON_CALLBACK', null, callback);
108+
browser.notifyWhenNoOutstandingRequests(notify);
109+
expect(notify).not.toHaveBeenCalled();
110+
expect(scripts.length).toEqual(1);
111+
var script = scripts[0];
112+
var url = script.src.split('?cb=');
113+
expect(url[0]).toEqual('http://example.org/path');
114+
expect(typeof fakeWindow[url[1]]).toEqual($function);
115+
fakeWindow[url[1]]('data');
116+
script.onload();
117+
118+
expect(notify).toHaveBeenCalled();
119+
expect(log).toEqual('200:data;');
120+
expect(scripts).toEqual(removedScripts);
121+
expect(fakeWindow[url[1]]).toBeUndefined();
122+
});
123+
124+
125+
it('should call callback when script fails to load', function() {
126+
browser.xhr('JSON', 'http://example.org/path?cb=JSON_CALLBACK', null, callback);
127+
var script = scripts[0];
128+
expect(typeof script.onload).toBe($function);
129+
expect(typeof script.onerror).toBe($function);
130+
script.onerror();
131+
132+
expect(log).toEqual('undefined:undefined;');
133+
});
134+
135+
136+
it('should update the outstandingRequests counter for successful requests', function() {
137+
var notify = jasmine.createSpy('notify');
138+
browser.xhr('JSON', 'http://example.org/path?cb=JSON_CALLBACK', null, callback);
139+
browser.notifyWhenNoOutstandingRequests(notify);
140+
expect(notify).not.toHaveBeenCalled();
141+
142+
var script = scripts[0];
143+
var url = script.src.split('?cb=');
144+
fakeWindow[url[1]]('data');
145+
script.onload();
146+
147+
expect(notify).toHaveBeenCalled();
148+
});
149+
150+
151+
it('should update the outstandingRequests counter for failed requests', function() {
152+
var notify = jasmine.createSpy('notify');
153+
browser.xhr('JSON', 'http://example.org/path?cb=JSON_CALLBACK', null, callback);
154+
browser.notifyWhenNoOutstandingRequests(notify);
155+
expect(notify).not.toHaveBeenCalled();
156+
157+
scripts[0].onerror();
158+
159+
expect(notify).toHaveBeenCalled();
160+
});
161+
}
109162
});
110163

164+
111165
it('should normalize IE\'s 1223 status code into 204', function() {
112166
var callback = jasmine.createSpy('XHR');
113167

0 commit comments

Comments
 (0)