diff --git a/src/AngularPublic.js b/src/AngularPublic.js index 9409999f4557..0de446d90085 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -72,6 +72,7 @@ $HttpParamSerializerProvider, $HttpParamSerializerJQLikeProvider, $HttpBackendProvider, + $xhrFactoryProvider, $LocationProvider, $LogProvider, $ParseProvider, @@ -230,6 +231,7 @@ function publishExternalAPI(angular) { $httpParamSerializer: $HttpParamSerializerProvider, $httpParamSerializerJQLike: $HttpParamSerializerJQLikeProvider, $httpBackend: $HttpBackendProvider, + $xhrFactory: $xhrFactoryProvider, $location: $LocationProvider, $log: $LogProvider, $parse: $ParseProvider, diff --git a/src/ng/httpBackend.js b/src/ng/httpBackend.js index b6aa9689796d..0b16b34a7748 100644 --- a/src/ng/httpBackend.js +++ b/src/ng/httpBackend.js @@ -1,7 +1,32 @@ 'use strict'; -function createXhr() { - return new window.XMLHttpRequest(); +/** + * @ngdoc service + * @name $xhrFactory + * + * @description + * Factory function used to create XMLHttpRequest objects. + * + * Replace or decorate this service to create your own custom XMLHttpRequest objects. + * + * ``` + * angular.module('myApp', []) + * .factory('$xhrFactory', function() { + * return function createXhr(method, url) { + * return new window.XMLHttpRequest({mozSystem: true}); + * }; + * }); + * ``` + * + * @param {string} method HTTP method of the request (GET, POST, PUT, ..) + * @param {string} url URL of the request. + */ +function $xhrFactoryProvider() { + this.$get = function() { + return function createXhr() { + return new window.XMLHttpRequest(); + }; + }; } /** @@ -9,6 +34,7 @@ function createXhr() { * @name $httpBackend * @requires $window * @requires $document + * @requires $xhrFactory * * @description * HTTP backend used by the {@link ng.$http service} that delegates to @@ -21,8 +47,8 @@ function createXhr() { * $httpBackend} which can be trained with responses. */ function $HttpBackendProvider() { - this.$get = ['$browser', '$window', '$document', function($browser, $window, $document) { - return createHttpBackend($browser, createXhr, $browser.defer, $window.angular.callbacks, $document[0]); + this.$get = ['$browser', '$window', '$document', '$xhrFactory', function($browser, $window, $document, $xhrFactory) { + return createHttpBackend($browser, $xhrFactory, $browser.defer, $window.angular.callbacks, $document[0]); }]; } @@ -46,7 +72,7 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc }); } else { - var xhr = createXhr(); + var xhr = createXhr(method, url); xhr.open(method, url, true); forEach(headers, function(value, key) { diff --git a/test/ng/httpBackendSpec.js b/test/ng/httpBackendSpec.js index 03490fc4ca1f..cd356959578d 100644 --- a/test/ng/httpBackendSpec.js +++ b/test/ng/httpBackendSpec.js @@ -233,6 +233,13 @@ describe('$httpBackend', function() { expect(MockXhr.$$lastInstance.withCredentials).toBe(true); }); + it('should call $xhrFactory with method and url', function() { + var mockXhrFactory = jasmine.createSpy('mockXhrFactory').andCallFake(createMockXhr); + $backend = createHttpBackend($browser, mockXhrFactory, $browser.defer, callbacks, fakeDocument); + $backend('GET', '/some-url', 'some-data', noop); + expect(mockXhrFactory).toHaveBeenCalledWith('GET', '/some-url'); + }); + describe('responseType', function() {