diff --git a/docs/content/error/httpBackend/noxhr.ngdoc b/docs/content/error/httpBackend/noxhr.ngdoc deleted file mode 100644 index 3ac5244c8c8e..000000000000 --- a/docs/content/error/httpBackend/noxhr.ngdoc +++ /dev/null @@ -1,9 +0,0 @@ -@ngdoc error -@name $httpBackend:noxhr -@fullName Unsupported XHR -@description - -This error occurs in browsers that do not support XmlHttpRequest. AngularJS -supports Safari, Chrome, Firefox, Opera, IE8 and higher, and mobile browsers -(Android, Chrome Mobile, iOS Safari). To avoid this error, use an officially -supported browser. \ No newline at end of file diff --git a/src/ng/httpBackend.js b/src/ng/httpBackend.js index 0bfe2fc32254..ffc51abf2957 100644 --- a/src/ng/httpBackend.js +++ b/src/ng/httpBackend.js @@ -1,12 +1,12 @@ 'use strict'; -var XHR = window.XMLHttpRequest || function() { +function createXhr(method) { + // IE8 doesn't support PATCH method, but the ActiveX object does /* global ActiveXObject */ - try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {} - try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {} - try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {} - throw minErr('$httpBackend')('noxhr', "This browser does not support XMLHttpRequest."); -}; + return (msie <= 8 && lowercase(method) === 'patch') + ? new ActiveXObject('Microsoft.XMLHTTP') + : new window.XMLHttpRequest(); +} /** @@ -28,11 +28,11 @@ var XHR = window.XMLHttpRequest || function() { */ function $HttpBackendProvider() { this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) { - return createHttpBackend($browser, XHR, $browser.defer, $window.angular.callbacks, $document[0]); + return createHttpBackend($browser, createXhr, $browser.defer, $window.angular.callbacks, $document[0]); }]; } -function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument) { +function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDocument) { var ABORTED = -1; // TODO(vojta): fix the signature @@ -57,7 +57,9 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument) delete callbacks[callbackId]; }); } else { - var xhr = new XHR(); + + var xhr = createXhr(method); + xhr.open(method, url, true); forEach(headers, function(value, key) { if (isDefined(value)) { @@ -73,7 +75,9 @@ function createHttpBackend($browser, XHR, $browserDefer, callbacks, rawDocument) // onreadystatechange might by called multiple times // with readyState === 4 on mobile webkit caused by // xhrs that are resolved while the app is in the background (see #5426). - xhr.onreadystatechange = undefined; + // + // we must delete the property instead of setting it to undefined/null to make IE8 happy. + delete xhr.onreadystatechange; var responseHeaders = null, response = null; diff --git a/src/ngMock/angular-mocks.js b/src/ngMock/angular-mocks.js index d11ef0c1ac23..fb7ef0573c20 100644 --- a/src/ngMock/angular-mocks.js +++ b/src/ngMock/angular-mocks.js @@ -1572,6 +1572,10 @@ function MockHttpExpectation(method, url, data, headers) { }; } +function createMockXhr() { + return new MockXhr(); +} + function MockXhr() { // hack for testing $http, $httpBackend diff --git a/test/ng/httpBackendSpec.js b/test/ng/httpBackendSpec.js index 5a392538939a..7302de003234 100644 --- a/test/ng/httpBackendSpec.js +++ b/test/ng/httpBackendSpec.js @@ -53,7 +53,7 @@ describe('$httpBackend', function() { }) } }; - $backend = createHttpBackend($browser, MockXhr, fakeTimeout, callbacks, fakeDocument); + $backend = createHttpBackend($browser, createMockXhr, fakeTimeout, callbacks, fakeDocument); callback = jasmine.createSpy('done'); })); @@ -250,7 +250,7 @@ describe('$httpBackend', function() { expect(response).toBe('response'); }); - $backend = createHttpBackend($browser, SyncXhr); + $backend = createHttpBackend($browser, function() { return new SyncXhr() }); $backend('GET', '/url', null, callback); expect(callback).toHaveBeenCalledOnce(); }); @@ -426,7 +426,7 @@ describe('$httpBackend', function() { it('should convert 0 to 200 if content', function() { - $backend = createHttpBackend($browser, MockXhr); + $backend = createHttpBackend($browser, createMockXhr); $backend('GET', 'file:///whatever/index.html', null, callback); respond(0, 'SOME CONTENT'); @@ -437,7 +437,7 @@ describe('$httpBackend', function() { it('should convert 0 to 404 if no content', function() { - $backend = createHttpBackend($browser, MockXhr); + $backend = createHttpBackend($browser, createMockXhr); $backend('GET', 'file:///whatever/index.html', null, callback); respond(0, ''); @@ -465,7 +465,7 @@ describe('$httpBackend', function() { try { - $backend = createHttpBackend($browser, MockXhr); + $backend = createHttpBackend($browser, createMockXhr); $backend('GET', '/whatever/index.html', null, callback); respond(0, ''); @@ -480,7 +480,7 @@ describe('$httpBackend', function() { it('should return original backend status code if different from 0', function () { - $backend = createHttpBackend($browser, MockXhr); + $backend = createHttpBackend($browser, createMockXhr); // request to http:// $backend('POST', 'http://rest_api/create_whatever', null, callback);