diff --git a/lib/core/AxiosHeaders.js b/lib/core/AxiosHeaders.js index 2212f77..fd996a3 100644 --- a/lib/core/AxiosHeaders.js +++ b/lib/core/AxiosHeaders.js @@ -100,9 +100,12 @@ class AxiosHeaders { setHeaders(header, valueOrRewrite) } else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) { setHeaders(parseHeaders(header), valueOrRewrite); - } else if (utils.isHeaders(header)) { - for (const [key, value] of header.entries()) { - setHeader(value, key, rewrite); + } else if (utils.isObject(header) && utils.isIterable(header)) { + for (const entry of header) { + if (!utils.isArray(entry)) { + throw TypeError('Object iterator must return a key-value pair'); + } + setHeader(entry[1], entry[0], rewrite); } } else { header != null && setHeader(valueOrRewrite, header, rewrite); diff --git a/lib/utils.js b/lib/utils.js index c48eb1e..a5ed039 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -6,6 +6,7 @@ import bind from './helpers/bind.js'; const {toString} = Object.prototype; const {getPrototypeOf} = Object; +const {iterator, toStringTag} = Symbol; const kindOf = (cache => thing => { const str = toString.call(thing); @@ -132,7 +133,7 @@ const isPlainObject = (val) => { } const prototype = getPrototypeOf(val); - return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in val) && !(Symbol.iterator in val); + return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val); } /** @@ -483,13 +484,13 @@ const isTypedArray = (TypedArray => { * @returns {void} */ const forEachEntry = (obj, fn) => { - const generator = obj && obj[Symbol.iterator]; + const generator = obj && obj[iterator]; - const iterator = generator.call(obj); + const _iterator = generator.call(obj); let result; - while ((result = iterator.next()) && !result.done) { + while ((result = _iterator.next()) && !result.done) { const pair = result.value; fn.call(obj, pair[0], pair[1]); } @@ -610,7 +611,7 @@ const toFiniteNumber = (value, defaultValue) => { * @returns {boolean} */ function isSpecCompliantForm(thing) { - return !!(thing && isFunction(thing.append) && thing[Symbol.toStringTag] === 'FormData' && thing[Symbol.iterator]); + return !!(thing && isFunction(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]); } const toJSONObject = (obj) => { @@ -679,6 +680,10 @@ const asap = typeof queueMicrotask !== 'undefined' ? // ********************* + +const isIterable = (thing) => thing != null && isFunction(thing[iterator]); + + export default { isArray, isArrayBuffer, @@ -734,5 +739,6 @@ export default { isAsyncFn, isThenable, setImmediate: _setImmediate, - asap + asap, + isIterable }; diff --git a/test/unit/core/AxiosHeaders.js b/test/unit/core/AxiosHeaders.js index e4e577b..0c5258c 100644 --- a/test/unit/core/AxiosHeaders.js +++ b/test/unit/core/AxiosHeaders.js @@ -73,7 +73,15 @@ describe('AxiosHeaders', function () { headers.set('foo', 'value2', true); assert.strictEqual(headers.get('foo'), 'value2'); - }) + }); + + it('should support iterables as a key-value source object', function () { + const headers = new AxiosHeaders(); + + headers.set(new Map([['x', '123']])); + + assert.strictEqual(headers.get('x'), '123'); + }); }); it('should support uppercase name mapping for names overlapped by class methods', () => {