From ec5f67db8ceb6ed9f7f0b4e46892e3e83dded373 Mon Sep 17 00:00:00 2001 From: Sjur Bakka Date: Thu, 18 Jun 2015 08:38:40 +0200 Subject: [PATCH] feat(http): add $xhrFactory service to enable creation of custom XMLHTTPRequest objects Closes #2318 --- src/AngularPublic.js | 2 ++ src/ng/httpBackend.js | 37 ++++++++++++++++++++++++++++++++----- test/ng/httpBackendSpec.js | 7 +++++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/AngularPublic.js b/src/AngularPublic.js index 3f530626d3e2..d3900df00154 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -72,6 +72,7 @@ $HttpParamSerializerProvider, $HttpParamSerializerJQLikeProvider, $HttpBackendProvider, + $xhrFactoryProvider, $LocationProvider, $LogProvider, $ParseProvider, @@ -233,6 +234,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 8bfd85516807..058d0839bcd8 100644 --- a/src/ng/httpBackend.js +++ b/src/ng/httpBackend.js @@ -1,7 +1,33 @@ 'use strict'; -function createXhr() { - return new window.XMLHttpRequest(); +/** + * @ngdoc service + * @name $xhrFactory + * + * @description + * Factory function used to create XMLHttpRequest objects. + * + * Decorate this service to create your own custom XMLHttpRequest objects. + * + * ``` + * .config(function($provide) { + * $provide.decorator('$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 +35,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 +48,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 +73,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 abe40d176bff..fd2fca9dcd87 100644 --- a/test/ng/httpBackendSpec.js +++ b/test/ng/httpBackendSpec.js @@ -231,6 +231,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() {