mirror of
https://github.com/tenrok/axios.git
synced 2026-06-20 20:00:40 +03:00
Fixed & Imporoved AxiosHeaders class (#5224)
* Refactored AxiosHeaders class; * Added support for instances of AxiosHeaders as a value for the headers option; Co-authored-by: Jay <jasonsaayman@gmail.com>
This commit is contained in:
Vendored
+5
-2
@@ -21,8 +21,7 @@ type AxiosHeaderTester = (matcher?: AxiosHeaderMatcher) => boolean;
|
|||||||
|
|
||||||
export class AxiosHeaders {
|
export class AxiosHeaders {
|
||||||
constructor(
|
constructor(
|
||||||
headers?: RawAxiosHeaders | AxiosHeaders,
|
headers?: RawAxiosHeaders | AxiosHeaders
|
||||||
defaultHeaders?: RawAxiosHeaders | AxiosHeaders
|
|
||||||
);
|
);
|
||||||
|
|
||||||
set(headerName?: string, value?: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders;
|
set(headerName?: string, value?: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders;
|
||||||
@@ -39,12 +38,16 @@ export class AxiosHeaders {
|
|||||||
|
|
||||||
normalize(format: boolean): AxiosHeaders;
|
normalize(format: boolean): AxiosHeaders;
|
||||||
|
|
||||||
|
concat(...targets: Array<AxiosHeaders | RawAxiosHeaders | string>): AxiosHeaders;
|
||||||
|
|
||||||
toJSON(asStrings?: boolean): RawAxiosHeaders;
|
toJSON(asStrings?: boolean): RawAxiosHeaders;
|
||||||
|
|
||||||
static from(thing?: AxiosHeaders | RawAxiosHeaders | string): AxiosHeaders;
|
static from(thing?: AxiosHeaders | RawAxiosHeaders | string): AxiosHeaders;
|
||||||
|
|
||||||
static accessor(header: string | string[]): AxiosHeaders;
|
static accessor(header: string | string[]): AxiosHeaders;
|
||||||
|
|
||||||
|
static concat(...targets: Array<AxiosHeaders | RawAxiosHeaders | string>): AxiosHeaders;
|
||||||
|
|
||||||
setContentType: AxiosHeaderSetter;
|
setContentType: AxiosHeaderSetter;
|
||||||
getContentType: AxiosHeaderGetter;
|
getContentType: AxiosHeaderGetter;
|
||||||
hasContentType: AxiosHeaderTester;
|
hasContentType: AxiosHeaderTester;
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ export default function httpAdapter(config) {
|
|||||||
data: convertedData,
|
data: convertedData,
|
||||||
status: 200,
|
status: 200,
|
||||||
statusText: 'OK',
|
statusText: 'OK',
|
||||||
headers: {},
|
headers: new AxiosHeaders(),
|
||||||
config
|
config
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -588,4 +588,4 @@ export default function httpAdapter(config) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const __setProxy = setProxy;
|
export const __setProxy = setProxy;
|
||||||
|
|||||||
@@ -75,5 +75,6 @@ axios.AxiosHeaders = AxiosHeaders;
|
|||||||
axios.formToJSON = thing => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);
|
axios.formToJSON = thing => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);
|
||||||
|
|
||||||
axios.default = axios;
|
axios.default = axios;
|
||||||
|
|
||||||
// this module should only have a default export
|
// this module should only have a default export
|
||||||
export default axios
|
export default axios
|
||||||
|
|||||||
+10
-8
@@ -47,7 +47,7 @@ class Axios {
|
|||||||
|
|
||||||
config = mergeConfig(this.defaults, config);
|
config = mergeConfig(this.defaults, config);
|
||||||
|
|
||||||
const {transitional, paramsSerializer} = config;
|
const {transitional, paramsSerializer, headers} = config;
|
||||||
|
|
||||||
if (transitional !== undefined) {
|
if (transitional !== undefined) {
|
||||||
validator.assertOptions(transitional, {
|
validator.assertOptions(transitional, {
|
||||||
@@ -67,20 +67,22 @@ class Axios {
|
|||||||
// Set config.method
|
// Set config.method
|
||||||
config.method = (config.method || this.defaults.method || 'get').toLowerCase();
|
config.method = (config.method || this.defaults.method || 'get').toLowerCase();
|
||||||
|
|
||||||
|
let contextHeaders;
|
||||||
|
|
||||||
// Flatten headers
|
// Flatten headers
|
||||||
const defaultHeaders = config.headers && utils.merge(
|
contextHeaders = headers && utils.merge(
|
||||||
config.headers.common,
|
headers.common,
|
||||||
config.headers[config.method]
|
headers[config.method]
|
||||||
);
|
);
|
||||||
|
|
||||||
defaultHeaders && utils.forEach(
|
contextHeaders && utils.forEach(
|
||||||
['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],
|
['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],
|
||||||
function cleanHeaderConfig(method) {
|
(method) => {
|
||||||
delete config.headers[method];
|
delete headers[method];
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
config.headers = new AxiosHeaders(config.headers, defaultHeaders);
|
config.headers = AxiosHeaders.concat(contextHeaders, headers);
|
||||||
|
|
||||||
// filter out skipped interceptors
|
// filter out skipped interceptors
|
||||||
const requestInterceptorChain = [];
|
const requestInterceptorChain = [];
|
||||||
|
|||||||
+93
-87
@@ -4,7 +4,6 @@ import utils from '../utils.js';
|
|||||||
import parseHeaders from '../helpers/parseHeaders.js';
|
import parseHeaders from '../helpers/parseHeaders.js';
|
||||||
|
|
||||||
const $internals = Symbol('internals');
|
const $internals = Symbol('internals');
|
||||||
const $defaults = Symbol('defaults');
|
|
||||||
|
|
||||||
function normalizeHeader(header) {
|
function normalizeHeader(header) {
|
||||||
return header && String(header).trim().toLowerCase();
|
return header && String(header).trim().toLowerCase();
|
||||||
@@ -30,6 +29,10 @@ function parseTokens(str) {
|
|||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isValidHeaderName(str) {
|
||||||
|
return /^[-_a-zA-Z]+$/.test(str.trim());
|
||||||
|
}
|
||||||
|
|
||||||
function matchHeaderValue(context, value, header, filter) {
|
function matchHeaderValue(context, value, header, filter) {
|
||||||
if (utils.isFunction(filter)) {
|
if (utils.isFunction(filter)) {
|
||||||
return filter.call(this, value, header);
|
return filter.call(this, value, header);
|
||||||
@@ -66,27 +69,12 @@ function buildAccessors(obj, header) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function findKey(obj, key) {
|
class AxiosHeaders {
|
||||||
key = key.toLowerCase();
|
constructor(headers) {
|
||||||
const keys = Object.keys(obj);
|
headers && this.set(headers);
|
||||||
let i = keys.length;
|
|
||||||
let _key;
|
|
||||||
while (i-- > 0) {
|
|
||||||
_key = keys[i];
|
|
||||||
if (key === _key.toLowerCase()) {
|
|
||||||
return _key;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function AxiosHeaders(headers, defaults) {
|
set(header, valueOrRewrite, rewrite) {
|
||||||
headers && this.set(headers);
|
|
||||||
this[$defaults] = defaults || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign(AxiosHeaders.prototype, {
|
|
||||||
set: function(header, valueOrRewrite, rewrite) {
|
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
function setHeader(_value, _header, _rewrite) {
|
function setHeader(_value, _header, _rewrite) {
|
||||||
@@ -96,69 +84,70 @@ Object.assign(AxiosHeaders.prototype, {
|
|||||||
throw new Error('header name must be a non-empty string');
|
throw new Error('header name must be a non-empty string');
|
||||||
}
|
}
|
||||||
|
|
||||||
const key = findKey(self, lHeader);
|
const key = utils.findKey(self, lHeader);
|
||||||
|
|
||||||
if (key && _rewrite !== true && (self[key] === false || _rewrite === false)) {
|
if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) {
|
||||||
return;
|
self[key || _header] = normalizeValue(_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
self[key || _header] = normalizeValue(_value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utils.isPlainObject(header)) {
|
const setHeaders = (headers, _rewrite) =>
|
||||||
utils.forEach(header, (_value, _header) => {
|
utils.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite));
|
||||||
setHeader(_value, _header, valueOrRewrite);
|
|
||||||
});
|
if (utils.isPlainObject(header) || header instanceof this.constructor) {
|
||||||
|
setHeaders(header, valueOrRewrite)
|
||||||
|
} else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {
|
||||||
|
setHeaders(parseHeaders(header), valueOrRewrite);
|
||||||
} else {
|
} else {
|
||||||
setHeader(valueOrRewrite, header, rewrite);
|
header != null && setHeader(valueOrRewrite, header, rewrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
}
|
||||||
|
|
||||||
get: function(header, parser) {
|
get(header, parser) {
|
||||||
header = normalizeHeader(header);
|
|
||||||
|
|
||||||
if (!header) return undefined;
|
|
||||||
|
|
||||||
const key = findKey(this, header);
|
|
||||||
|
|
||||||
if (key) {
|
|
||||||
const value = this[key];
|
|
||||||
|
|
||||||
if (!parser) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parser === true) {
|
|
||||||
return parseTokens(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (utils.isFunction(parser)) {
|
|
||||||
return parser.call(this, value, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (utils.isRegExp(parser)) {
|
|
||||||
return parser.exec(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new TypeError('parser must be boolean|regexp|function');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
has: function(header, matcher) {
|
|
||||||
header = normalizeHeader(header);
|
header = normalizeHeader(header);
|
||||||
|
|
||||||
if (header) {
|
if (header) {
|
||||||
const key = findKey(this, header);
|
const key = utils.findKey(this, header);
|
||||||
|
|
||||||
|
if (key) {
|
||||||
|
const value = this[key];
|
||||||
|
|
||||||
|
if (!parser) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parser === true) {
|
||||||
|
return parseTokens(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (utils.isFunction(parser)) {
|
||||||
|
return parser.call(this, value, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (utils.isRegExp(parser)) {
|
||||||
|
return parser.exec(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new TypeError('parser must be boolean|regexp|function');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
has(header, matcher) {
|
||||||
|
header = normalizeHeader(header);
|
||||||
|
|
||||||
|
if (header) {
|
||||||
|
const key = utils.findKey(this, header);
|
||||||
|
|
||||||
return !!(key && (!matcher || matchHeaderValue(this, this[key], key, matcher)));
|
return !!(key && (!matcher || matchHeaderValue(this, this[key], key, matcher)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
}
|
||||||
|
|
||||||
delete: function(header, matcher) {
|
delete(header, matcher) {
|
||||||
const self = this;
|
const self = this;
|
||||||
let deleted = false;
|
let deleted = false;
|
||||||
|
|
||||||
@@ -166,7 +155,7 @@ Object.assign(AxiosHeaders.prototype, {
|
|||||||
_header = normalizeHeader(_header);
|
_header = normalizeHeader(_header);
|
||||||
|
|
||||||
if (_header) {
|
if (_header) {
|
||||||
const key = findKey(self, _header);
|
const key = utils.findKey(self, _header);
|
||||||
|
|
||||||
if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) {
|
if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) {
|
||||||
delete self[key];
|
delete self[key];
|
||||||
@@ -183,18 +172,18 @@ Object.assign(AxiosHeaders.prototype, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return deleted;
|
return deleted;
|
||||||
},
|
}
|
||||||
|
|
||||||
clear: function() {
|
clear() {
|
||||||
return Object.keys(this).forEach(this.delete.bind(this));
|
return Object.keys(this).forEach(this.delete.bind(this));
|
||||||
},
|
}
|
||||||
|
|
||||||
normalize: function(format) {
|
normalize(format) {
|
||||||
const self = this;
|
const self = this;
|
||||||
const headers = {};
|
const headers = {};
|
||||||
|
|
||||||
utils.forEach(this, (value, header) => {
|
utils.forEach(this, (value, header) => {
|
||||||
const key = findKey(headers, header);
|
const key = utils.findKey(headers, header);
|
||||||
|
|
||||||
if (key) {
|
if (key) {
|
||||||
self[key] = normalizeValue(value);
|
self[key] = normalizeValue(value);
|
||||||
@@ -214,30 +203,47 @@ Object.assign(AxiosHeaders.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
}
|
||||||
|
|
||||||
toJSON: function(asStrings) {
|
concat(...targets) {
|
||||||
|
return this.constructor.concat(this, ...targets);
|
||||||
|
}
|
||||||
|
|
||||||
|
toJSON(asStrings) {
|
||||||
const obj = Object.create(null);
|
const obj = Object.create(null);
|
||||||
|
|
||||||
utils.forEach(Object.assign({}, this[$defaults] || null, this),
|
utils.forEach(this, (value, header) => {
|
||||||
(value, header) => {
|
value != null && value !== false && (obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value);
|
||||||
if (value == null || value === false) return;
|
});
|
||||||
obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value;
|
|
||||||
});
|
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
Object.assign(AxiosHeaders, {
|
[Symbol.iterator]() {
|
||||||
from: function(thing) {
|
return Object.entries(this.toJSON())[Symbol.iterator]();
|
||||||
if (utils.isString(thing)) {
|
}
|
||||||
return new this(parseHeaders(thing));
|
|
||||||
}
|
toString() {
|
||||||
|
return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
get [Symbol.toStringTag]() {
|
||||||
|
return 'AxiosHeaders';
|
||||||
|
}
|
||||||
|
|
||||||
|
static from(thing) {
|
||||||
return thing instanceof this ? thing : new this(thing);
|
return thing instanceof this ? thing : new this(thing);
|
||||||
},
|
}
|
||||||
|
|
||||||
accessor: function(header) {
|
static concat(first, ...targets) {
|
||||||
|
const computed = new this(first);
|
||||||
|
|
||||||
|
targets.forEach((target) => computed.set(target));
|
||||||
|
|
||||||
|
return computed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static accessor(header) {
|
||||||
const internals = this[$internals] = (this[$internals] = {
|
const internals = this[$internals] = (this[$internals] = {
|
||||||
accessors: {}
|
accessors: {}
|
||||||
});
|
});
|
||||||
@@ -258,7 +264,7 @@ Object.assign(AxiosHeaders, {
|
|||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
AxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent']);
|
AxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent']);
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,10 @@ export default function dispatchRequest(config) {
|
|||||||
config.transformRequest
|
config.transformRequest
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (['post', 'put', 'patch'].indexOf(config.method) !== -1) {
|
||||||
|
config.headers.setContentType('application/x-www-form-urlencoded', false);
|
||||||
|
}
|
||||||
|
|
||||||
const adapter = config.adapter || defaults.adapter;
|
const adapter = config.adapter || defaults.adapter;
|
||||||
|
|
||||||
return adapter(config).then(function onAdapterResolution(response) {
|
return adapter(config).then(function onAdapterResolution(response) {
|
||||||
|
|||||||
+50
-46
@@ -1,6 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import utils from '../utils.js';
|
import utils from '../utils.js';
|
||||||
|
import AxiosHeaders from "./AxiosHeaders.js";
|
||||||
|
|
||||||
|
const headersToObject = (thing) => thing instanceof AxiosHeaders ? thing.toJSON() : thing;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Config-specific merge-function which creates a new config-object
|
* Config-specific merge-function which creates a new config-object
|
||||||
@@ -16,9 +19,9 @@ export default function mergeConfig(config1, config2) {
|
|||||||
config2 = config2 || {};
|
config2 = config2 || {};
|
||||||
const config = {};
|
const config = {};
|
||||||
|
|
||||||
function getMergedValue(target, source) {
|
function getMergedValue(target, source, caseless) {
|
||||||
if (utils.isPlainObject(target) && utils.isPlainObject(source)) {
|
if (utils.isPlainObject(target) && utils.isPlainObject(source)) {
|
||||||
return utils.merge(target, source);
|
return utils.merge.call({caseless}, target, source);
|
||||||
} else if (utils.isPlainObject(source)) {
|
} else if (utils.isPlainObject(source)) {
|
||||||
return utils.merge({}, source);
|
return utils.merge({}, source);
|
||||||
} else if (utils.isArray(source)) {
|
} else if (utils.isArray(source)) {
|
||||||
@@ -28,72 +31,73 @@ export default function mergeConfig(config1, config2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line consistent-return
|
// eslint-disable-next-line consistent-return
|
||||||
function mergeDeepProperties(prop) {
|
function mergeDeepProperties(a, b, caseless) {
|
||||||
if (!utils.isUndefined(config2[prop])) {
|
if (!utils.isUndefined(b)) {
|
||||||
return getMergedValue(config1[prop], config2[prop]);
|
return getMergedValue(a, b, caseless);
|
||||||
} else if (!utils.isUndefined(config1[prop])) {
|
} else if (!utils.isUndefined(a)) {
|
||||||
return getMergedValue(undefined, config1[prop]);
|
return getMergedValue(undefined, a, caseless);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line consistent-return
|
// eslint-disable-next-line consistent-return
|
||||||
function valueFromConfig2(prop) {
|
function valueFromConfig2(a, b) {
|
||||||
if (!utils.isUndefined(config2[prop])) {
|
if (!utils.isUndefined(b)) {
|
||||||
return getMergedValue(undefined, config2[prop]);
|
return getMergedValue(undefined, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line consistent-return
|
// eslint-disable-next-line consistent-return
|
||||||
function defaultToConfig2(prop) {
|
function defaultToConfig2(a, b) {
|
||||||
if (!utils.isUndefined(config2[prop])) {
|
if (!utils.isUndefined(b)) {
|
||||||
return getMergedValue(undefined, config2[prop]);
|
return getMergedValue(undefined, b);
|
||||||
} else if (!utils.isUndefined(config1[prop])) {
|
} else if (!utils.isUndefined(a)) {
|
||||||
return getMergedValue(undefined, config1[prop]);
|
return getMergedValue(undefined, a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line consistent-return
|
// eslint-disable-next-line consistent-return
|
||||||
function mergeDirectKeys(prop) {
|
function mergeDirectKeys(a, b, prop) {
|
||||||
if (prop in config2) {
|
if (prop in config2) {
|
||||||
return getMergedValue(config1[prop], config2[prop]);
|
return getMergedValue(a, b);
|
||||||
} else if (prop in config1) {
|
} else if (prop in config1) {
|
||||||
return getMergedValue(undefined, config1[prop]);
|
return getMergedValue(undefined, a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mergeMap = {
|
const mergeMap = {
|
||||||
'url': valueFromConfig2,
|
url: valueFromConfig2,
|
||||||
'method': valueFromConfig2,
|
method: valueFromConfig2,
|
||||||
'data': valueFromConfig2,
|
data: valueFromConfig2,
|
||||||
'baseURL': defaultToConfig2,
|
baseURL: defaultToConfig2,
|
||||||
'transformRequest': defaultToConfig2,
|
transformRequest: defaultToConfig2,
|
||||||
'transformResponse': defaultToConfig2,
|
transformResponse: defaultToConfig2,
|
||||||
'paramsSerializer': defaultToConfig2,
|
paramsSerializer: defaultToConfig2,
|
||||||
'timeout': defaultToConfig2,
|
timeout: defaultToConfig2,
|
||||||
'timeoutMessage': defaultToConfig2,
|
timeoutMessage: defaultToConfig2,
|
||||||
'withCredentials': defaultToConfig2,
|
withCredentials: defaultToConfig2,
|
||||||
'adapter': defaultToConfig2,
|
adapter: defaultToConfig2,
|
||||||
'responseType': defaultToConfig2,
|
responseType: defaultToConfig2,
|
||||||
'xsrfCookieName': defaultToConfig2,
|
xsrfCookieName: defaultToConfig2,
|
||||||
'xsrfHeaderName': defaultToConfig2,
|
xsrfHeaderName: defaultToConfig2,
|
||||||
'onUploadProgress': defaultToConfig2,
|
onUploadProgress: defaultToConfig2,
|
||||||
'onDownloadProgress': defaultToConfig2,
|
onDownloadProgress: defaultToConfig2,
|
||||||
'decompress': defaultToConfig2,
|
decompress: defaultToConfig2,
|
||||||
'maxContentLength': defaultToConfig2,
|
maxContentLength: defaultToConfig2,
|
||||||
'maxBodyLength': defaultToConfig2,
|
maxBodyLength: defaultToConfig2,
|
||||||
'beforeRedirect': defaultToConfig2,
|
beforeRedirect: defaultToConfig2,
|
||||||
'transport': defaultToConfig2,
|
transport: defaultToConfig2,
|
||||||
'httpAgent': defaultToConfig2,
|
httpAgent: defaultToConfig2,
|
||||||
'httpsAgent': defaultToConfig2,
|
httpsAgent: defaultToConfig2,
|
||||||
'cancelToken': defaultToConfig2,
|
cancelToken: defaultToConfig2,
|
||||||
'socketPath': defaultToConfig2,
|
socketPath: defaultToConfig2,
|
||||||
'responseEncoding': defaultToConfig2,
|
responseEncoding: defaultToConfig2,
|
||||||
'validateStatus': mergeDirectKeys
|
validateStatus: mergeDirectKeys,
|
||||||
|
headers: (a, b) => mergeDeepProperties(headersToObject(a), headersToObject(b), true)
|
||||||
};
|
};
|
||||||
|
|
||||||
utils.forEach(Object.keys(config1).concat(Object.keys(config2)), function computeConfigValue(prop) {
|
utils.forEach(Object.keys(config1).concat(Object.keys(config2)), function computeConfigValue(prop) {
|
||||||
const merge = mergeMap[prop] || mergeDeepProperties;
|
const merge = mergeMap[prop] || mergeDeepProperties;
|
||||||
const configValue = merge(prop);
|
const configValue = merge(config1[prop], config2[prop], prop);
|
||||||
(utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);
|
(utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import formDataToJSON from '../helpers/formDataToJSON.js';
|
|||||||
import adapters from '../adapters/index.js';
|
import adapters from '../adapters/index.js';
|
||||||
|
|
||||||
const DEFAULT_CONTENT_TYPE = {
|
const DEFAULT_CONTENT_TYPE = {
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
'Content-Type': undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+36
-8
@@ -228,7 +228,7 @@ const trim = (str) => str.trim ?
|
|||||||
* @param {Function} fn The callback to invoke for each item
|
* @param {Function} fn The callback to invoke for each item
|
||||||
*
|
*
|
||||||
* @param {Boolean} [allOwnKeys = false]
|
* @param {Boolean} [allOwnKeys = false]
|
||||||
* @returns {void}
|
* @returns {any}
|
||||||
*/
|
*/
|
||||||
function forEach(obj, fn, {allOwnKeys = false} = {}) {
|
function forEach(obj, fn, {allOwnKeys = false} = {}) {
|
||||||
// Don't bother if no value provided
|
// Don't bother if no value provided
|
||||||
@@ -263,6 +263,24 @@ function forEach(obj, fn, {allOwnKeys = false} = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findKey(obj, key) {
|
||||||
|
key = key.toLowerCase();
|
||||||
|
const keys = Object.keys(obj);
|
||||||
|
let i = keys.length;
|
||||||
|
let _key;
|
||||||
|
while (i-- > 0) {
|
||||||
|
_key = keys[i];
|
||||||
|
if (key === _key.toLowerCase()) {
|
||||||
|
return _key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const _global = typeof self === "undefined" ? typeof global === "undefined" ? this : global : self;
|
||||||
|
|
||||||
|
const isContextDefined = (context) => !isUndefined(context) && context !== _global;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accepts varargs expecting each argument to be an object, then
|
* Accepts varargs expecting each argument to be an object, then
|
||||||
* immutably merges the properties of each object and returns result.
|
* immutably merges the properties of each object and returns result.
|
||||||
@@ -282,16 +300,18 @@ function forEach(obj, fn, {allOwnKeys = false} = {}) {
|
|||||||
* @returns {Object} Result of all merge properties
|
* @returns {Object} Result of all merge properties
|
||||||
*/
|
*/
|
||||||
function merge(/* obj1, obj2, obj3, ... */) {
|
function merge(/* obj1, obj2, obj3, ... */) {
|
||||||
|
const {caseless} = isContextDefined(this) && this || {};
|
||||||
const result = {};
|
const result = {};
|
||||||
const assignValue = (val, key) => {
|
const assignValue = (val, key) => {
|
||||||
if (isPlainObject(result[key]) && isPlainObject(val)) {
|
const targetKey = caseless && findKey(result, key) || key;
|
||||||
result[key] = merge(result[key], val);
|
if (isPlainObject(result[targetKey]) && isPlainObject(val)) {
|
||||||
|
result[targetKey] = merge(result[targetKey], val);
|
||||||
} else if (isPlainObject(val)) {
|
} else if (isPlainObject(val)) {
|
||||||
result[key] = merge({}, val);
|
result[targetKey] = merge({}, val);
|
||||||
} else if (isArray(val)) {
|
} else if (isArray(val)) {
|
||||||
result[key] = val.slice();
|
result[targetKey] = val.slice();
|
||||||
} else {
|
} else {
|
||||||
result[key] = val;
|
result[targetKey] = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,6 +547,11 @@ const reduceDescriptors = (obj, reducer) => {
|
|||||||
|
|
||||||
const freezeMethods = (obj) => {
|
const freezeMethods = (obj) => {
|
||||||
reduceDescriptors(obj, (descriptor, name) => {
|
reduceDescriptors(obj, (descriptor, name) => {
|
||||||
|
// skip restricted props in strict mode
|
||||||
|
if (isFunction(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const value = obj[name];
|
const value = obj[name];
|
||||||
|
|
||||||
if (!isFunction(value)) return;
|
if (!isFunction(value)) return;
|
||||||
@@ -540,7 +565,7 @@ const freezeMethods = (obj) => {
|
|||||||
|
|
||||||
if (!descriptor.set) {
|
if (!descriptor.set) {
|
||||||
descriptor.set = () => {
|
descriptor.set = () => {
|
||||||
throw Error('Can not read-only method \'' + name + '\'');
|
throw Error('Can not rewrite read-only method \'' + name + '\'');
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -609,5 +634,8 @@ export default {
|
|||||||
toObjectSet,
|
toObjectSet,
|
||||||
toCamelCase,
|
toCamelCase,
|
||||||
noop,
|
noop,
|
||||||
toFiniteNumber
|
toFiniteNumber,
|
||||||
|
findKey,
|
||||||
|
global: _global,
|
||||||
|
isContextDefined
|
||||||
};
|
};
|
||||||
|
|||||||
+1
-1
@@ -15,6 +15,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|||||||
const exec = util.promisify(cp.exec);
|
const exec = util.promisify(cp.exec);
|
||||||
|
|
||||||
const {Axios} = axiosFactory;
|
const {Axios} = axiosFactory;
|
||||||
|
|
||||||
const ignoreList = ['default'];
|
const ignoreList = ['default'];
|
||||||
|
|
||||||
const instance = axiosFactory.create({});
|
const instance = axiosFactory.create({});
|
||||||
@@ -133,5 +134,4 @@ describe('module', function () {
|
|||||||
await exec(`npm test --prefix ${pkgPath}`, {});
|
await exec(`npm test --prefix ${pkgPath}`, {});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import defaults from '../../../lib/defaults';
|
import defaults from '../../../lib/defaults';
|
||||||
import mergeConfig from '../../../lib/core/mergeConfig';
|
import mergeConfig from '../../../lib/core/mergeConfig';
|
||||||
|
import {AxiosHeaders} from "../../../index.js";
|
||||||
|
|
||||||
describe('core::mergeConfig', function() {
|
describe('core::mergeConfig', function() {
|
||||||
it('should accept undefined for second argument', function() {
|
it('should accept undefined for second argument', function() {
|
||||||
@@ -100,6 +101,27 @@ describe('core::mergeConfig', function() {
|
|||||||
expect(merged.nestedConfig.propertyOnRequestConfig).toEqual(true);
|
expect(merged.nestedConfig.propertyOnRequestConfig).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('headers', ()=> {
|
||||||
|
it('should allow merging with AxiosHeaders instances', () => {
|
||||||
|
const merged = mergeConfig({
|
||||||
|
headers: new AxiosHeaders({
|
||||||
|
x: 1,
|
||||||
|
y: 2
|
||||||
|
})
|
||||||
|
}, {
|
||||||
|
headers: new AxiosHeaders({
|
||||||
|
X: 1,
|
||||||
|
Y: 2
|
||||||
|
})
|
||||||
|
});
|
||||||
|
expect(merged.headers).toEqual({
|
||||||
|
x: '1',
|
||||||
|
y: '2'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('valueFromConfig2Keys', function() {
|
describe('valueFromConfig2Keys', function() {
|
||||||
const config1 = {url: '/foo', method: 'post', data: {a: 3}};
|
const config1 = {url: '/foo', method: 'post', data: {a: 3}};
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
const {AxiosHeaders} = axios;
|
||||||
|
|
||||||
function testHeaderValue(headers, key, val) {
|
function testHeaderValue(headers, key, val) {
|
||||||
let found = false;
|
let found = false;
|
||||||
|
|
||||||
@@ -106,12 +108,35 @@ describe('headers', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should preserve content-type if data is false', function (done) {
|
it('should preserve content-type if data is false', async function () {
|
||||||
axios.post('/foo', false);
|
axios.post('/foo', false);
|
||||||
|
|
||||||
getAjaxRequest().then(function (request) {
|
await getAjaxRequest().then(function (request) {
|
||||||
testHeaderValue(request.requestHeaders, 'Content-Type', 'application/x-www-form-urlencoded');
|
testHeaderValue(request.requestHeaders, 'Content-Type', 'application/x-www-form-urlencoded');
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should allow an AxiosHeaders instance to be used as the value of the headers option', async ()=> {
|
||||||
|
const instance = axios.create({
|
||||||
|
headers: new AxiosHeaders({
|
||||||
|
xFoo: 'foo',
|
||||||
|
xBar: 'bar'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.get('/foo', {
|
||||||
|
headers: {
|
||||||
|
XFOO: 'foo2',
|
||||||
|
xBaz: 'baz'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await getAjaxRequest().then(function (request) {
|
||||||
|
expect(request.requestHeaders.xFoo).toEqual('foo2');
|
||||||
|
expect(request.requestHeaders.xBar).toEqual('bar');
|
||||||
|
expect(request.requestHeaders.xBaz).toEqual('baz');
|
||||||
|
expect(request.requestHeaders.XFOO).toEqual(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import AxiosHeaders from "../../lib/core/AxiosHeaders.js";
|
||||||
|
|
||||||
describe('options', function () {
|
describe('options', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
jasmine.Ajax.install();
|
jasmine.Ajax.install();
|
||||||
|
|||||||
@@ -83,4 +83,14 @@ describe('utils::merge', function () {
|
|||||||
expect(d).toEqual({a: [1, 2, 3]});
|
expect(d).toEqual({a: [1, 2, 3]});
|
||||||
expect(d.a).not.toBe(a);
|
expect(d.a).not.toBe(a);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should support caseless option', ()=> {
|
||||||
|
const a = {x: 1};
|
||||||
|
const b = {X: 2};
|
||||||
|
const merged = merge.call({caseless: true}, a, b);
|
||||||
|
|
||||||
|
expect(merged).toEqual({
|
||||||
|
x: 2
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1393,6 +1393,7 @@ describe('supports http with nodejs', function () {
|
|||||||
|
|
||||||
it('should omit a user-agent if one is explicitly disclaimed', function (done) {
|
it('should omit a user-agent if one is explicitly disclaimed', function (done) {
|
||||||
server = http.createServer(function (req, res) {
|
server = http.createServer(function (req, res) {
|
||||||
|
console.log(req.headers);
|
||||||
assert.equal("user-agent" in req.headers, false);
|
assert.equal("user-agent" in req.headers, false);
|
||||||
assert.equal("User-Agent" in req.headers, false);
|
assert.equal("User-Agent" in req.headers, false);
|
||||||
res.end();
|
res.end();
|
||||||
|
|||||||
@@ -33,7 +33,16 @@ describe('AxiosHeaders', function () {
|
|||||||
|
|
||||||
assert.strictEqual(headers.get('foo'), 'value1');
|
assert.strictEqual(headers.get('foo'), 'value1');
|
||||||
assert.strictEqual(headers.get('bar'), 'value2');
|
assert.strictEqual(headers.get('bar'), 'value2');
|
||||||
})
|
});
|
||||||
|
|
||||||
|
it('should support adding multiple headers from raw headers string', function(){
|
||||||
|
const headers = new AxiosHeaders();
|
||||||
|
|
||||||
|
headers.set(`foo:value1\nbar:value2`);
|
||||||
|
|
||||||
|
assert.strictEqual(headers.get('foo'), 'value1');
|
||||||
|
assert.strictEqual(headers.get('bar'), 'value2');
|
||||||
|
});
|
||||||
|
|
||||||
it('should not rewrite header the header if the value is false', function(){
|
it('should not rewrite header the header if the value is false', function(){
|
||||||
const headers = new AxiosHeaders();
|
const headers = new AxiosHeaders();
|
||||||
@@ -338,4 +347,49 @@ describe('AxiosHeaders', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('AxiosHeaders.concat', function () {
|
||||||
|
it('should concatenate plain headers into an AxiosHeader instance', function () {
|
||||||
|
const a = {a: 1};
|
||||||
|
const b = {b: 2};
|
||||||
|
const c = {c: 3};
|
||||||
|
const headers = AxiosHeaders.concat(a, b, c);
|
||||||
|
|
||||||
|
assert.deepStrictEqual({...headers.toJSON()}, {
|
||||||
|
a: '1',
|
||||||
|
b: '2',
|
||||||
|
c: '3'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should concatenate raw headers into an AxiosHeader instance', function () {
|
||||||
|
const a = 'a:1\nb:2';
|
||||||
|
const b = 'c:3\nx:4';
|
||||||
|
const headers = AxiosHeaders.concat(a, b);
|
||||||
|
|
||||||
|
assert.deepStrictEqual({...headers.toJSON()}, {
|
||||||
|
a: '1',
|
||||||
|
b: '2',
|
||||||
|
c: '3',
|
||||||
|
x: '4'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should concatenate Axios headers into a new AxiosHeader instance', function () {
|
||||||
|
const a = new AxiosHeaders({x: 1});
|
||||||
|
const b = new AxiosHeaders({y: 2});
|
||||||
|
const headers = AxiosHeaders.concat(a, b);
|
||||||
|
|
||||||
|
assert.deepStrictEqual({...headers.toJSON()}, {
|
||||||
|
x: '1',
|
||||||
|
y: '2'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('toString', function () {
|
||||||
|
it('should serialize AxiosHeader instance to a raw headers string', function () {
|
||||||
|
assert.deepStrictEqual(new AxiosHeaders({x:1, y:2}).toString(), 'x: 1\ny: 2');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user