From 6c17d02bc4cc02f478775d62e1f9f77da9da82ad Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Fri, 13 Dec 2013 01:49:37 -0800 Subject: [PATCH 1/2] fix($httpBackend): use ActiveX XHR when making PATCH requests on IE8 IE8's native XHR doesn't support PATCH requests, but the ActiveX one does. I'm also removing the noxhr error doc because nobody will ever get that error. Closes #2518 Closes #5043 --- docs/content/error/httpBackend/noxhr.ngdoc | 9 --------- src/ng/httpBackend.js | 20 +++++++++++--------- src/ngMock/angular-mocks.js | 4 ++++ test/ng/httpBackendSpec.js | 12 ++++++------ 4 files changed, 21 insertions(+), 24 deletions(-) delete mode 100644 docs/content/error/httpBackend/noxhr.ngdoc 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..c72ae4bbecd6 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)) { 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); From fd9a03e147aac7e952c6dda1f381fd4662276ba2 Mon Sep 17 00:00:00 2001 From: Igor Minar Date: Thu, 2 Jan 2014 22:47:39 -0800 Subject: [PATCH 2/2] fix(httpBackend): fix 'type mismatch' error on IE8 after each request --- src/ng/httpBackend.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ng/httpBackend.js b/src/ng/httpBackend.js index c72ae4bbecd6..ffc51abf2957 100644 --- a/src/ng/httpBackend.js +++ b/src/ng/httpBackend.js @@ -75,7 +75,9 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc // 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;