mirror of
https://github.com/tenrok/axios.git
synced 2026-06-23 20:40:40 +03:00
URL params serializer; (#4734)
* Refactored BuildURL helper to use URLSearchParams serializer; * Updated typings; Added TS test;
This commit is contained in:
Vendored
+17
-5
@@ -90,22 +90,34 @@ export interface GenericAbortSignal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface FormDataVisitorHelpers {
|
export interface FormDataVisitorHelpers {
|
||||||
defaultVisitor: FormDataVisitor;
|
defaultVisitor: SerializerVisitor;
|
||||||
convertValue: (value: any) => any;
|
convertValue: (value: any) => any;
|
||||||
isVisitable: (value: any) => boolean;
|
isVisitable: (value: any) => boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FormDataVisitor {
|
export interface SerializerVisitor {
|
||||||
(value: any, key: string | number, path: null | Array<string | number>, helpers: FormDataVisitorHelpers): boolean;
|
(value: any, key: string | number, path: null | Array<string | number>, helpers: FormDataVisitorHelpers): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FormSerializerOptions {
|
export interface SerializerOptions {
|
||||||
visitor?: FormDataVisitor;
|
visitor?: SerializerVisitor;
|
||||||
dots?: boolean;
|
dots?: boolean;
|
||||||
metaTokens?: boolean;
|
metaTokens?: boolean;
|
||||||
indexes?: boolean;
|
indexes?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tslint:disable-next-line
|
||||||
|
export interface FormSerializerOptions extends SerializerOptions {
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ParamEncoder {
|
||||||
|
(value: any, defaultEncoder: (value: any) => any): any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ParamsSerializerOptions extends SerializerOptions {
|
||||||
|
encode?: ParamEncoder;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AxiosRequestConfig<D = any> {
|
export interface AxiosRequestConfig<D = any> {
|
||||||
url?: string;
|
url?: string;
|
||||||
method?: Method | string;
|
method?: Method | string;
|
||||||
@@ -114,7 +126,7 @@ export interface AxiosRequestConfig<D = any> {
|
|||||||
transformResponse?: AxiosResponseTransformer | AxiosResponseTransformer[];
|
transformResponse?: AxiosResponseTransformer | AxiosResponseTransformer[];
|
||||||
headers?: AxiosRequestHeaders;
|
headers?: AxiosRequestHeaders;
|
||||||
params?: any;
|
params?: any;
|
||||||
paramsSerializer?: (params: any) => string;
|
paramsSerializer?: ParamsSerializerOptions;
|
||||||
data?: D;
|
data?: D;
|
||||||
timeout?: number;
|
timeout?: number;
|
||||||
timeoutErrorMessage?: string;
|
timeoutErrorMessage?: string;
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var toFormData = require('./toFormData');
|
||||||
|
|
||||||
|
function encode(str) {
|
||||||
|
var charMap = {
|
||||||
|
'!': '%21',
|
||||||
|
"'": '%27',
|
||||||
|
'(': '%28',
|
||||||
|
')': '%29',
|
||||||
|
'~': '%7E',
|
||||||
|
'%20': '+',
|
||||||
|
'%00': '\x00'
|
||||||
|
};
|
||||||
|
return encodeURIComponent(str).replace(/[!'\(\)~]|%20|%00/g, function replacer(match) {
|
||||||
|
return charMap[match];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function AxiosURLSearchParams(params, options) {
|
||||||
|
this._pairs = [];
|
||||||
|
|
||||||
|
params && toFormData(params, this, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
var prototype = AxiosURLSearchParams.prototype;
|
||||||
|
|
||||||
|
prototype.append = function append(name, value) {
|
||||||
|
this._pairs.push([name, value]);
|
||||||
|
};
|
||||||
|
|
||||||
|
prototype.toString = function toString(encoder) {
|
||||||
|
var _encode = encoder ? function(value) {
|
||||||
|
return encoder.call(this, value, encode);
|
||||||
|
} : encode;
|
||||||
|
|
||||||
|
return this._pairs.map(function each(pair) {
|
||||||
|
return _encode(pair[0]) + '=' + _encode(pair[1]);
|
||||||
|
}, '').join('&');
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = AxiosURLSearchParams;
|
||||||
+14
-38
@@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var utils = require('./../utils');
|
var utils = require('../utils');
|
||||||
|
var AxiosURLSearchParams = require('../helpers/AxiosURLSearchParams');
|
||||||
|
|
||||||
function encode(val) {
|
function encode(val) {
|
||||||
return encodeURIComponent(val).
|
return encodeURIComponent(val).
|
||||||
@@ -17,54 +18,29 @@ function encode(val) {
|
|||||||
*
|
*
|
||||||
* @param {string} url The base of the url (e.g., http://www.google.com)
|
* @param {string} url The base of the url (e.g., http://www.google.com)
|
||||||
* @param {object} [params] The params to be appended
|
* @param {object} [params] The params to be appended
|
||||||
* @param {?object} paramsSerializer
|
* @param {?object} options
|
||||||
* @returns {string} The formatted url
|
* @returns {string} The formatted url
|
||||||
*/
|
*/
|
||||||
module.exports = function buildURL(url, params, paramsSerializer) {
|
module.exports = function buildURL(url, params, options) {
|
||||||
/*eslint no-param-reassign:0*/
|
/*eslint no-param-reassign:0*/
|
||||||
if (!params) {
|
if (!params) {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
var serializedParams;
|
var hashmarkIndex = url.indexOf('#');
|
||||||
if (paramsSerializer) {
|
|
||||||
serializedParams = paramsSerializer(params);
|
|
||||||
} else if (utils.isURLSearchParams(params)) {
|
|
||||||
serializedParams = params.toString();
|
|
||||||
} else {
|
|
||||||
var parts = [];
|
|
||||||
|
|
||||||
utils.forEach(params, function serialize(val, key) {
|
if (hashmarkIndex !== -1) {
|
||||||
if (val === null || typeof val === 'undefined') {
|
url = url.slice(0, hashmarkIndex);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (utils.isArray(val)) {
|
|
||||||
key = key + '[]';
|
|
||||||
} else {
|
|
||||||
val = [val];
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.forEach(val, function parseValue(v) {
|
|
||||||
if (utils.isDate(v)) {
|
|
||||||
v = v.toISOString();
|
|
||||||
} else if (utils.isObject(v)) {
|
|
||||||
v = JSON.stringify(v);
|
|
||||||
}
|
|
||||||
parts.push(encode(key) + '=' + encode(v));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
serializedParams = parts.join('&');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serializedParams) {
|
var _encode = options && options.encode || encode;
|
||||||
var hashmarkIndex = url.indexOf('#');
|
|
||||||
if (hashmarkIndex !== -1) {
|
|
||||||
url = url.slice(0, hashmarkIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;
|
var serializerParams = utils.isURLSearchParams(params) ?
|
||||||
|
params.toString() :
|
||||||
|
new AxiosURLSearchParams(params, options).toString(_encode);
|
||||||
|
|
||||||
|
if (serializerParams) {
|
||||||
|
url += (url.indexOf('?') === -1 ? '?' : '&') + serializerParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
|
|||||||
@@ -46,6 +46,10 @@ function isSpecCompliant(thing) {
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
function toFormData(obj, formData, options) {
|
function toFormData(obj, formData, options) {
|
||||||
|
if (!utils.isObject(obj)) {
|
||||||
|
throw new TypeError('target must be an object');
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
formData = formData || new (envFormData || FormData)();
|
formData = formData || new (envFormData || FormData)();
|
||||||
|
|
||||||
|
|||||||
@@ -1,36 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = typeof URLSearchParams !== 'undefined' ? URLSearchParams : (function defineURLSearchParams() {
|
var AxiosURLSearchParams = require('../../../helpers/AxiosURLSearchParams');
|
||||||
function encode(str) {
|
|
||||||
var charMap = {
|
|
||||||
'!': '%21',
|
|
||||||
"'": '%27',
|
|
||||||
'(': '%28',
|
|
||||||
')': '%29',
|
|
||||||
'~': '%7E',
|
|
||||||
'%20': '+',
|
|
||||||
'%00': '\x00'
|
|
||||||
};
|
|
||||||
return encodeURIComponent(str).replace(/[!'\(\)~]|%20|%00/g, function replacer(match) {
|
|
||||||
return charMap[match];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function URLSearchParams() {
|
module.exports = typeof URLSearchParams !== 'undefined' ? URLSearchParams : AxiosURLSearchParams;
|
||||||
this.pairs = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
var prototype = URLSearchParams.prototype;
|
|
||||||
|
|
||||||
prototype.append = function append(name, value) {
|
|
||||||
this.pairs.push([name, value]);
|
|
||||||
};
|
|
||||||
|
|
||||||
prototype.toString = function toString() {
|
|
||||||
return this.pairs.map(function each(pair) {
|
|
||||||
return pair[0] + '=' + encode(pair[1]);
|
|
||||||
}, '').join('&');
|
|
||||||
};
|
|
||||||
|
|
||||||
return URLSearchParams;
|
|
||||||
})();
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ describe('helpers::buildURL', function () {
|
|||||||
foo: {
|
foo: {
|
||||||
bar: 'baz'
|
bar: 'baz'
|
||||||
}
|
}
|
||||||
})).toEqual('/foo?foo=' + encodeURI('{"bar":"baz"}'));
|
})).toEqual('/foo?foo[bar]=baz');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support date params', function () {
|
it('should support date params', function () {
|
||||||
@@ -60,15 +60,6 @@ describe('helpers::buildURL', function () {
|
|||||||
})).toEqual('/foo?foo=bar&query=baz');
|
})).toEqual('/foo?foo=bar&query=baz');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use serializer if provided', function () {
|
|
||||||
serializer = sinon.stub();
|
|
||||||
params = {foo: 'bar'};
|
|
||||||
serializer.returns('foo=bar');
|
|
||||||
expect(buildURL('/foo', params, serializer)).toEqual('/foo?foo=bar');
|
|
||||||
expect(serializer.calledOnce).toBe(true);
|
|
||||||
expect(serializer.calledWith(params)).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should support URLSearchParams', function () {
|
it('should support URLSearchParams', function () {
|
||||||
expect(buildURL('/foo', new URLSearchParams('bar=baz'))).toEqual('/foo?bar=baz');
|
expect(buildURL('/foo', new URLSearchParams('bar=baz'))).toEqual('/foo?bar=baz');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -20,7 +20,10 @@ const config: AxiosRequestConfig = {
|
|||||||
],
|
],
|
||||||
headers: { 'X-FOO': 'bar' },
|
headers: { 'X-FOO': 'bar' },
|
||||||
params: { id: 12345 },
|
params: { id: 12345 },
|
||||||
paramsSerializer: (params: any) => 'id=12345',
|
paramsSerializer: {
|
||||||
|
indexes: true,
|
||||||
|
encode: (value) => value
|
||||||
|
},
|
||||||
data: { foo: 'bar' },
|
data: { foo: 'bar' },
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user