Skip to content

Commit 1b1f9cc

Browse files
fix(headers): allow iterable objects to be a data source for the set method; (#6873)
1 parent 47a611f commit 1b1f9cc

3 files changed

Lines changed: 27 additions & 10 deletions

File tree

lib/core/AxiosHeaders.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,12 @@ class AxiosHeaders {
100100
setHeaders(header, valueOrRewrite)
101101
} else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {
102102
setHeaders(parseHeaders(header), valueOrRewrite);
103-
} else if (utils.isHeaders(header)) {
104-
for (const [key, value] of header.entries()) {
105-
setHeader(value, key, rewrite);
103+
} else if (utils.isObject(header) && utils.isIterable(header)) {
104+
for (const entry of header) {
105+
if (!utils.isArray(entry)) {
106+
throw TypeError('Object iterator must return a key-value pair');
107+
}
108+
setHeader(entry[1], entry[0], rewrite);
106109
}
107110
} else {
108111
header != null && setHeader(valueOrRewrite, header, rewrite);

lib/utils.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import bind from './helpers/bind.js';
66

77
const {toString} = Object.prototype;
88
const {getPrototypeOf} = Object;
9+
const {iterator, toStringTag} = Symbol;
910

1011
const kindOf = (cache => thing => {
1112
const str = toString.call(thing);
@@ -132,7 +133,7 @@ const isPlainObject = (val) => {
132133
}
133134

134135
const prototype = getPrototypeOf(val);
135-
return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in val) && !(Symbol.iterator in val);
136+
return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val);
136137
}
137138

138139
/**
@@ -483,13 +484,13 @@ const isTypedArray = (TypedArray => {
483484
* @returns {void}
484485
*/
485486
const forEachEntry = (obj, fn) => {
486-
const generator = obj && obj[Symbol.iterator];
487+
const generator = obj && obj[iterator];
487488

488-
const iterator = generator.call(obj);
489+
const _iterator = generator.call(obj);
489490

490491
let result;
491492

492-
while ((result = iterator.next()) && !result.done) {
493+
while ((result = _iterator.next()) && !result.done) {
493494
const pair = result.value;
494495
fn.call(obj, pair[0], pair[1]);
495496
}
@@ -610,7 +611,7 @@ const toFiniteNumber = (value, defaultValue) => {
610611
* @returns {boolean}
611612
*/
612613
function isSpecCompliantForm(thing) {
613-
return !!(thing && isFunction(thing.append) && thing[Symbol.toStringTag] === 'FormData' && thing[Symbol.iterator]);
614+
return !!(thing && isFunction(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]);
614615
}
615616

616617
const toJSONObject = (obj) => {
@@ -679,6 +680,10 @@ const asap = typeof queueMicrotask !== 'undefined' ?
679680

680681
// *********************
681682

683+
684+
const isIterable = (thing) => thing != null && isFunction(thing[iterator]);
685+
686+
682687
export default {
683688
isArray,
684689
isArrayBuffer,
@@ -734,5 +739,6 @@ export default {
734739
isAsyncFn,
735740
isThenable,
736741
setImmediate: _setImmediate,
737-
asap
742+
asap,
743+
isIterable
738744
};

test/unit/core/AxiosHeaders.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,15 @@ describe('AxiosHeaders', function () {
7373
headers.set('foo', 'value2', true);
7474

7575
assert.strictEqual(headers.get('foo'), 'value2');
76-
})
76+
});
77+
78+
it('should support iterables as a key-value source object', function () {
79+
const headers = new AxiosHeaders();
80+
81+
headers.set(new Map([['x', '123']]));
82+
83+
assert.strictEqual(headers.get('x'), '123');
84+
});
7785
});
7886

7987
it('should support uppercase name mapping for names overlapped by class methods', () => {

0 commit comments

Comments
 (0)