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:
+93
-87
@@ -4,7 +4,6 @@ import utils from '../utils.js';
|
||||
import parseHeaders from '../helpers/parseHeaders.js';
|
||||
|
||||
const $internals = Symbol('internals');
|
||||
const $defaults = Symbol('defaults');
|
||||
|
||||
function normalizeHeader(header) {
|
||||
return header && String(header).trim().toLowerCase();
|
||||
@@ -30,6 +29,10 @@ function parseTokens(str) {
|
||||
return tokens;
|
||||
}
|
||||
|
||||
function isValidHeaderName(str) {
|
||||
return /^[-_a-zA-Z]+$/.test(str.trim());
|
||||
}
|
||||
|
||||
function matchHeaderValue(context, value, header, filter) {
|
||||
if (utils.isFunction(filter)) {
|
||||
return filter.call(this, value, header);
|
||||
@@ -66,27 +69,12 @@ function buildAccessors(obj, header) {
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
class AxiosHeaders {
|
||||
constructor(headers) {
|
||||
headers && this.set(headers);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function AxiosHeaders(headers, defaults) {
|
||||
headers && this.set(headers);
|
||||
this[$defaults] = defaults || null;
|
||||
}
|
||||
|
||||
Object.assign(AxiosHeaders.prototype, {
|
||||
set: function(header, valueOrRewrite, rewrite) {
|
||||
set(header, valueOrRewrite, rewrite) {
|
||||
const self = this;
|
||||
|
||||
function setHeader(_value, _header, _rewrite) {
|
||||
@@ -96,69 +84,70 @@ Object.assign(AxiosHeaders.prototype, {
|
||||
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)) {
|
||||
return;
|
||||
if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) {
|
||||
self[key || _header] = normalizeValue(_value);
|
||||
}
|
||||
|
||||
self[key || _header] = normalizeValue(_value);
|
||||
}
|
||||
|
||||
if (utils.isPlainObject(header)) {
|
||||
utils.forEach(header, (_value, _header) => {
|
||||
setHeader(_value, _header, valueOrRewrite);
|
||||
});
|
||||
const setHeaders = (headers, _rewrite) =>
|
||||
utils.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite));
|
||||
|
||||
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 {
|
||||
setHeader(valueOrRewrite, header, rewrite);
|
||||
header != null && setHeader(valueOrRewrite, header, rewrite);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
}
|
||||
|
||||
get: function(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) {
|
||||
get(header, parser) {
|
||||
header = normalizeHeader(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 false;
|
||||
},
|
||||
}
|
||||
|
||||
delete: function(header, matcher) {
|
||||
delete(header, matcher) {
|
||||
const self = this;
|
||||
let deleted = false;
|
||||
|
||||
@@ -166,7 +155,7 @@ Object.assign(AxiosHeaders.prototype, {
|
||||
_header = normalizeHeader(_header);
|
||||
|
||||
if (_header) {
|
||||
const key = findKey(self, _header);
|
||||
const key = utils.findKey(self, _header);
|
||||
|
||||
if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) {
|
||||
delete self[key];
|
||||
@@ -183,18 +172,18 @@ Object.assign(AxiosHeaders.prototype, {
|
||||
}
|
||||
|
||||
return deleted;
|
||||
},
|
||||
}
|
||||
|
||||
clear: function() {
|
||||
clear() {
|
||||
return Object.keys(this).forEach(this.delete.bind(this));
|
||||
},
|
||||
}
|
||||
|
||||
normalize: function(format) {
|
||||
normalize(format) {
|
||||
const self = this;
|
||||
const headers = {};
|
||||
|
||||
utils.forEach(this, (value, header) => {
|
||||
const key = findKey(headers, header);
|
||||
const key = utils.findKey(headers, header);
|
||||
|
||||
if (key) {
|
||||
self[key] = normalizeValue(value);
|
||||
@@ -214,30 +203,47 @@ Object.assign(AxiosHeaders.prototype, {
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
}
|
||||
|
||||
toJSON: function(asStrings) {
|
||||
concat(...targets) {
|
||||
return this.constructor.concat(this, ...targets);
|
||||
}
|
||||
|
||||
toJSON(asStrings) {
|
||||
const obj = Object.create(null);
|
||||
|
||||
utils.forEach(Object.assign({}, this[$defaults] || null, this),
|
||||
(value, header) => {
|
||||
if (value == null || value === false) return;
|
||||
obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value;
|
||||
});
|
||||
utils.forEach(this, (value, header) => {
|
||||
value != null && value !== false && (obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value);
|
||||
});
|
||||
|
||||
return obj;
|
||||
}
|
||||
});
|
||||
|
||||
Object.assign(AxiosHeaders, {
|
||||
from: function(thing) {
|
||||
if (utils.isString(thing)) {
|
||||
return new this(parseHeaders(thing));
|
||||
}
|
||||
[Symbol.iterator]() {
|
||||
return Object.entries(this.toJSON())[Symbol.iterator]();
|
||||
}
|
||||
|
||||
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);
|
||||
},
|
||||
}
|
||||
|
||||
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] = {
|
||||
accessors: {}
|
||||
});
|
||||
@@ -258,7 +264,7 @@ Object.assign(AxiosHeaders, {
|
||||
|
||||
return this;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
AxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent']);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user