Skip to content

Commit 7b30f1a

Browse files
committed
XDR for IE;
See angular#1047 (comment) PR
1 parent 29274e1 commit 7b30f1a

File tree

2 files changed

+69
-32
lines changed

2 files changed

+69
-32
lines changed

src/ng/http.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,7 @@ function $HttpProvider() {
564564
* requests with credentials} for more information.
565565
* - **responseType** - `{string}` - see {@link
566566
* https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType requestType}.
567+
* - **useXDomain** 0 `{boolean}` - use XDomainRequest in IE requests
567568
*
568569
* @returns {HttpPromise} Returns a {@link ng.$q promise} object with the
569570
* standard `then` method and two http specific methods: `success` and `error`. The `then`
@@ -965,7 +966,7 @@ function $HttpProvider() {
965966
// if we won't have the response in cache, send the request to the backend
966967
if (isUndefined(cachedResp)) {
967968
$httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout,
968-
config.withCredentials, config.responseType);
969+
config.withCredentials, config.responseType, config.useXDomain || $http.defaults.useXDomain);
969970
}
970971

971972
return promise;

src/ng/httpBackend.js

Lines changed: 67 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ var XHR = window.XMLHttpRequest || function() {
66
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {}
77
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {}
88
throw minErr('$httpBackend')('noxhr', "This browser does not support XMLHttpRequest.");
9-
};
9+
}, XDR = !window.msPerformance && window.XDomainRequest || null;
1010

1111

1212
/**
@@ -28,14 +28,14 @@ var XHR = window.XMLHttpRequest || function() {
2828
*/
2929
function $HttpBackendProvider() {
3030
this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) {
31-
return createHttpBackend($browser, XHR, $browser.defer, $window.angular.callbacks,
31+
return createHttpBackend($browser, XHR, XDR, $browser.defer, $window.angular.callbacks,
3232
$document[0], $window.location.protocol.replace(':', ''));
3333
}];
3434
}
3535

36-
function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument, locationProtocol) {
36+
function createHttpBackend($browser, XHR, XDR, $browserDefer, callbacks, rawDocument, locationProtocol) {
3737
// TODO(vojta): fix the signature
38-
return function(method, url, post, callback, headers, timeout, withCredentials, responseType) {
38+
return function(method, url, post, callback, headers, timeout, withCredentials, responseType, useXDomain) {
3939
var status;
4040
$browser.$$incOutstandingRequestCount();
4141
url = url || $browser.url();
@@ -56,39 +56,75 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument,
5656
delete callbacks[callbackId];
5757
});
5858
} else {
59-
var xhr = new XHR();
60-
xhr.open(method, url, true);
61-
forEach(headers, function(value, key) {
62-
if (isDefined(value)) {
63-
xhr.setRequestHeader(key, value);
59+
var status;
60+
if (useXDomain && XDR) {
61+
var xdr = new XDR();
62+
xdr.open(method.toLowerCase(), url);
63+
64+
// Required to XDomainRequest works
65+
xdr.timeout = timeout;
66+
xdr.onprogress = function() {};
67+
68+
xdr.ontimeout = function() {
69+
completeRequest(callback, 408, 'Timeout', 'Content-Type: text/plain');
70+
xdr.abort();
71+
};
72+
73+
xdr.onload = function() {
74+
completeRequest(callback, 200, xdr.responseText, 'Content-Type: ' + xdr.contentType);
75+
};
76+
77+
xdr.onerror = function() {
78+
completeRequest(callback, 500, 'Error', 'Content-Type: text/plain');
79+
xdr.abort();
80+
};
81+
82+
83+
$browserDefer(function () {
84+
xdr.send();
85+
}, 0); //fix IE bug that raises '$apply already in progress' on cached requests
86+
87+
if (timeout > 0) {
88+
$browserDefer(function() {
89+
status = -1;
90+
xdr.abort();
91+
}, timeout);
6492
}
65-
});
93+
} else {
94+
var xhr = new XHR();
95+
xhr.open(method, url, true);
96+
forEach(headers, function(value, key) {
97+
if (isDefined(value)) {
98+
xhr.setRequestHeader(key, value);
99+
}
100+
});
101+
102+
// In IE6 and 7, this might be called synchronously when xhr.send below is called and the
103+
// response is in the cache. the promise api will ensure that to the app code the api is
104+
// always async
105+
xhr.onreadystatechange = function() {
106+
if (xhr.readyState == 4) {
107+
var responseHeaders = xhr.getAllResponseHeaders();
108+
109+
// responseText is the old-school way of retrieving response (supported by IE8 & 9)
110+
// response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
111+
completeRequest(callback,
112+
status || xhr.status,
113+
(xhr.responseType ? xhr.response : xhr.responseText),
114+
responseHeaders);
115+
}
116+
};
66117

67-
// In IE6 and 7, this might be called synchronously when xhr.send below is called and the
68-
// response is in the cache. the promise api will ensure that to the app code the api is
69-
// always async
70-
xhr.onreadystatechange = function() {
71-
if (xhr.readyState == 4) {
72-
var responseHeaders = xhr.getAllResponseHeaders();
73-
74-
// responseText is the old-school way of retrieving response (supported by IE8 & 9)
75-
// response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
76-
completeRequest(callback,
77-
status || xhr.status,
78-
(xhr.responseType ? xhr.response : xhr.responseText),
79-
responseHeaders);
118+
if (withCredentials) {
119+
xhr.withCredentials = true;
80120
}
81-
};
82121

83-
if (withCredentials) {
84-
xhr.withCredentials = true;
85-
}
122+
if (responseType) {
123+
xhr.responseType = responseType;
124+
}
86125

87-
if (responseType) {
88-
xhr.responseType = responseType;
126+
xhr.send(post || null);
89127
}
90-
91-
xhr.send(post || null);
92128
}
93129

94130
if (timeout > 0) {

0 commit comments

Comments
 (0)