mirror of
https://github.com/tenrok/axios.git
synced 2026-06-17 19:21:29 +03:00
Fix: Don't add null values to query string. (#5108)
* feat: add boolean flag to mimic pre 1.x behavior for paramsSerializer custom function * chore: update ParamsSerializer Readme * fix: dont slice hash off URL if not appending params * Omit nulls from formData serialization * fix: dont add nulls or undefined values to arrays either * readme update * fix test * chore: documentation * chore: do TS properly Co-authored-by: Jay <jasonsaayman@gmail.com>
This commit is contained in:
committed by
GitHub
parent
ef1c48a476
commit
b0ebf9fcac
@@ -358,6 +358,8 @@ These are the available config options for making requests. Only the `url` is re
|
|||||||
|
|
||||||
// `paramsSerializer` is an optional config in charge of serializing `params`
|
// `paramsSerializer` is an optional config in charge of serializing `params`
|
||||||
paramsSerializer: {
|
paramsSerializer: {
|
||||||
|
encode?: (param: string): string => { /* Do custom ops here and return transformed string */ }, // custom encoder function; sends Key/Values in an iterative fashion
|
||||||
|
serialize?: (params: Record<string, any>, options?: ParamsSerializerOptions ), // mimic pre 1.x behavior and send entire params object to a custom serializer func. Allows consumer to control how params are serialized.
|
||||||
indexes: false // array indexes format (null - no brackets, false (default) - empty brackets, true - brackets with indexes)
|
indexes: false // array indexes format (null - no brackets, false (default) - empty brackets, true - brackets with indexes)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -248,7 +248,7 @@ export interface ParamEncoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface CustomParamsSerializer {
|
export interface CustomParamsSerializer {
|
||||||
(params: object, options?: ParamsSerializerOptions): string;
|
(params: Record<string, any>, options?: ParamsSerializerOptions): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ParamsSerializerOptions extends SerializerOptions {
|
export interface ParamsSerializerOptions extends SerializerOptions {
|
||||||
|
|||||||
@@ -36,12 +36,6 @@ export default function buildURL(url, params, options) {
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hashmarkIndex = url.indexOf('#');
|
|
||||||
|
|
||||||
if (hashmarkIndex !== -1) {
|
|
||||||
url = url.slice(0, hashmarkIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
const _encode = options && options.encode || encode;
|
const _encode = options && options.encode || encode;
|
||||||
|
|
||||||
const serializeFn = options && options.serialize;
|
const serializeFn = options && options.serialize;
|
||||||
@@ -57,6 +51,11 @@ export default function buildURL(url, params, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (serializedParams) {
|
if (serializedParams) {
|
||||||
|
const hashmarkIndex = url.indexOf("#");
|
||||||
|
|
||||||
|
if (hashmarkIndex !== -1) {
|
||||||
|
url = url.slice(0, hashmarkIndex);
|
||||||
|
}
|
||||||
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;
|
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ function toFormData(obj, formData, options) {
|
|||||||
key = removeBrackets(key);
|
key = removeBrackets(key);
|
||||||
|
|
||||||
arr.forEach(function each(el, index) {
|
arr.forEach(function each(el, index) {
|
||||||
!utils.isUndefined(el) && formData.append(
|
!(utils.isUndefined(el) || el === null) && formData.append(
|
||||||
// eslint-disable-next-line no-nested-ternary
|
// eslint-disable-next-line no-nested-ternary
|
||||||
indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'),
|
indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'),
|
||||||
convertValue(el)
|
convertValue(el)
|
||||||
@@ -205,7 +205,7 @@ function toFormData(obj, formData, options) {
|
|||||||
stack.push(value);
|
stack.push(value);
|
||||||
|
|
||||||
utils.forEach(value, function each(el, key) {
|
utils.forEach(value, function each(el, key) {
|
||||||
const result = !utils.isUndefined(el) && visitor.call(
|
const result = !(utils.isUndefined(el) || el === null) && visitor.call(
|
||||||
formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers
|
formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,31 @@ describe('helpers::buildURL', function () {
|
|||||||
|
|
||||||
it('should support params', function () {
|
it('should support params', function () {
|
||||||
expect(buildURL('/foo', {
|
expect(buildURL('/foo', {
|
||||||
foo: 'bar'
|
foo: 'bar',
|
||||||
|
isUndefined: undefined,
|
||||||
|
isNull: null
|
||||||
})).toEqual('/foo?foo=bar');
|
})).toEqual('/foo?foo=bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should support sending raw params to custom serializer func', function () {
|
||||||
|
const serializer = sinon.stub();
|
||||||
|
const params = { foo: "bar" };
|
||||||
|
serializer.returns("foo=bar");
|
||||||
|
expect(
|
||||||
|
buildURL(
|
||||||
|
"/foo",
|
||||||
|
{
|
||||||
|
foo: "bar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
serialize: serializer,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
).toEqual("/foo?foo=bar");
|
||||||
|
expect(serializer.calledOnce).toBe(true);
|
||||||
|
expect(serializer.calledWith(params)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
it('should support object params', function () {
|
it('should support object params', function () {
|
||||||
expect(buildURL('/foo', {
|
expect(buildURL('/foo', {
|
||||||
foo: {
|
foo: {
|
||||||
@@ -30,7 +51,7 @@ describe('helpers::buildURL', function () {
|
|||||||
|
|
||||||
it('should support array params', function () {
|
it('should support array params', function () {
|
||||||
expect(buildURL('/foo', {
|
expect(buildURL('/foo', {
|
||||||
foo: ['bar', 'baz']
|
foo: ['bar', 'baz', null, undefined]
|
||||||
})).toEqual('/foo?foo[]=bar&foo[]=baz');
|
})).toEqual('/foo?foo[]=bar&foo[]=baz');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import axios, {
|
|||||||
AxiosAdapter,
|
AxiosAdapter,
|
||||||
Cancel,
|
Cancel,
|
||||||
CancelTokenSource,
|
CancelTokenSource,
|
||||||
Canceler, AxiosProgressEvent
|
Canceler, AxiosProgressEvent, ParamsSerializerOptions
|
||||||
} from 'axios';
|
} from 'axios';
|
||||||
|
|
||||||
const config: AxiosRequestConfig = {
|
const config: AxiosRequestConfig = {
|
||||||
@@ -21,8 +21,8 @@ const config: AxiosRequestConfig = {
|
|||||||
params: { id: 12345 },
|
params: { id: 12345 },
|
||||||
paramsSerializer: {
|
paramsSerializer: {
|
||||||
indexes: true,
|
indexes: true,
|
||||||
encode: (value) => value,
|
encode: (value: any) => value,
|
||||||
serialize: (value, options) => String(value)
|
serialize: (value: Record<string, any>, options?: ParamsSerializerOptions) => String(value)
|
||||||
},
|
},
|
||||||
data: { foo: 'bar' },
|
data: { foo: 'bar' },
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
|
|||||||
Reference in New Issue
Block a user