diff --git a/lib/axios.js b/lib/axios.js index ed1f519..68621dd 100644 --- a/lib/axios.js +++ b/lib/axios.js @@ -32,7 +32,7 @@ axios.Axios = Axios; // Factory for creating new instances axios.create = function create(instanceConfig) { - return createInstance(utils.merge(defaults, instanceConfig)); + return createInstance(utils.mergeConfig(axios.defaults, instanceConfig || {})); }; // Expose Cancel & CancelToken diff --git a/lib/core/Axios.js b/lib/core/Axios.js index f1af3e7..766a897 100644 --- a/lib/core/Axios.js +++ b/lib/core/Axios.js @@ -1,6 +1,5 @@ 'use strict'; -var defaults = require('./../defaults'); var utils = require('./../utils'); var InterceptorManager = require('./InterceptorManager'); var dispatchRequest = require('./dispatchRequest'); @@ -24,15 +23,20 @@ function Axios(instanceConfig) { * @param {Object} config The config specific for this request (merged with this.defaults) */ Axios.prototype.request = function request(config) { + config = config || {}; + /*eslint no-param-reassign:0*/ // Allow for axios('example/url'[, config]) a la fetch API if (typeof config === 'string') { - config = utils.merge({ - url: arguments[0] - }, arguments[1]); + config = arguments[1] || {}; + config.url = arguments[0]; } - config = utils.merge(defaults, this.defaults, { method: 'get' }, config); + if (!config.method) { + config.method = 'get'; + } + + config = utils.mergeConfig(this.defaults, config); config.method = config.method.toLowerCase(); // Hook up interceptors middleware diff --git a/lib/utils.js b/lib/utils.js index b3fd865..342fa1f 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -279,6 +279,51 @@ function extend(a, b, thisArg) { return a; } +function mergeConfig(defaults, instanceConfig) { + var config = {}; + forEach(['url', 'method', 'params', 'data'], function(prop) { + config[prop] = instanceConfig[prop]; + }); + forEach(['headers', 'auth', 'proxy'], function(prop) { + if (!isUndefined(instanceConfig[prop])) { + if (!isObject(instanceConfig[prop])) { + config[prop] = instanceConfig[prop]; + } else { + config[prop] = merge( + defaults[prop], + instanceConfig[prop] + ); + } + } else if (!isUndefined(defaults[prop])) { + config[prop] = JSON.parse(JSON.stringify(defaults[prop])); + } + }); + var remainingProperties = [ + 'baseURL', + 'transformRequest', + 'transformResponse', + 'paramsSerializer', + 'timeout', + 'withCredentials', + 'adapter', + 'responseType', + 'xsrfCookieName', + 'xsrfHeaderName', + 'onUploadProgress', + 'onDownloadProgress', + 'maxContentLength', + 'validateStatus', + 'maxRedirects', + 'httpAgent', + 'httpsAgent', + 'cancelToken' + ]; + forEach(remainingProperties, function(prop) { + config[prop] = !isUndefined(instanceConfig[prop]) ? instanceConfig[prop] : defaults[prop]; + }); + return config; +} + module.exports = { isArray: isArray, isArrayBuffer: isArrayBuffer, @@ -299,5 +344,6 @@ module.exports = { forEach: forEach, merge: merge, extend: extend, - trim: trim + trim: trim, + mergeConfig: mergeConfig }; diff --git a/test/specs/defaults.spec.js b/test/specs/defaults.spec.js index de19b6a..c8ee72e 100644 --- a/test/specs/defaults.spec.js +++ b/test/specs/defaults.spec.js @@ -148,14 +148,14 @@ describe('defaults', function () { }); }); - it('should be used by custom instance if set after instance created', function (done) { + it('should not be used by custom instance if set after instance created', function (done) { var instance = axios.create(); axios.defaults.baseURL = 'http://example.org/'; instance.get('/foo'); getAjaxRequest().then(function (request) { - expect(request.url).toBe('http://example.org/foo'); + expect(request.url).toBe('/foo'); done(); }); }); diff --git a/test/specs/options.spec.js b/test/specs/options.spec.js index 6520b8a..762b851 100644 --- a/test/specs/options.spec.js +++ b/test/specs/options.spec.js @@ -81,4 +81,32 @@ describe('options', function () { done(); }); }); + + it('should change only the baseURL of the specified instance', function() { + var instance1 = axios.create(); + var instance2 = axios.create(); + + instance1.defaults.baseURL = 'http://instance1.example.com/'; + + expect(instance2.defaults.baseURL).not.toBe('http://instance1.example.com/'); + }); + + it('should change only the headers of the specified instance', function() { + var instance1 = axios.create(); + var instance2 = axios.create(); + + instance1.defaults.headers.common.Authorization = 'faketoken'; + instance2.defaults.headers.common.Authorization = 'differentfaketoken'; + + instance1.defaults.headers.common['Content-Type'] = 'application/xml'; + instance2.defaults.headers.common['Content-Type'] = 'application/x-www-form-urlencoded'; + + expect(axios.defaults.headers.common.Authorization).toBe(undefined); + expect(instance1.defaults.headers.common.Authorization).toBe('faketoken'); + expect(instance2.defaults.headers.common.Authorization).toBe('differentfaketoken'); + + expect(axios.defaults.headers.common['Content-Type']).toBe(undefined); + expect(instance1.defaults.headers.common['Content-Type']).toBe('application/xml'); + expect(instance2.defaults.headers.common['Content-Type']).toBe('application/x-www-form-urlencoded'); + }); });