mirror of
https://github.com/tenrok/axios.git
synced 2026-06-20 20:00:40 +03:00
Added axios.formToJSON method; (#4735)
* Draft * Added `formDataToJSON` helper; Added `axios.formToJSON` method; Added client tests; Co-authored-by: Jay <jasonsaayman@gmail.com>
This commit is contained in:
Vendored
+7
@@ -300,6 +300,12 @@ export interface GenericFormData {
|
|||||||
append(name: string, value: any, options?: any): any;
|
append(name: string, value: any, options?: any): any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface GenericHTMLFormElement {
|
||||||
|
name: string;
|
||||||
|
method: string;
|
||||||
|
submit(): void;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AxiosStatic extends AxiosInstance {
|
export interface AxiosStatic extends AxiosInstance {
|
||||||
create(config?: CreateAxiosDefaults): AxiosInstance;
|
create(config?: CreateAxiosDefaults): AxiosInstance;
|
||||||
Cancel: CancelStatic;
|
Cancel: CancelStatic;
|
||||||
@@ -312,6 +318,7 @@ export interface AxiosStatic extends AxiosInstance {
|
|||||||
spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R;
|
spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R;
|
||||||
isAxiosError<T = any, D = any>(payload: any): payload is AxiosError<T, D>;
|
isAxiosError<T = any, D = any>(payload: any): payload is AxiosError<T, D>;
|
||||||
toFormData(sourceObj: object, targetFormData?: GenericFormData, options?: FormSerializerOptions): GenericFormData;
|
toFormData(sourceObj: object, targetFormData?: GenericFormData, options?: FormSerializerOptions): GenericFormData;
|
||||||
|
formToJSON(form: GenericFormData|GenericHTMLFormElement): object;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare const axios: AxiosStatic;
|
declare const axios: AxiosStatic;
|
||||||
|
|||||||
+5
-1
@@ -5,7 +5,7 @@ var bind = require('./helpers/bind');
|
|||||||
var Axios = require('./core/Axios');
|
var Axios = require('./core/Axios');
|
||||||
var mergeConfig = require('./core/mergeConfig');
|
var mergeConfig = require('./core/mergeConfig');
|
||||||
var defaults = require('./defaults');
|
var defaults = require('./defaults');
|
||||||
|
var formDataToJSON = require('./helpers/formDataToJSON');
|
||||||
/**
|
/**
|
||||||
* Create an instance of Axios
|
* Create an instance of Axios
|
||||||
*
|
*
|
||||||
@@ -58,6 +58,10 @@ axios.spread = require('./helpers/spread');
|
|||||||
// Expose isAxiosError
|
// Expose isAxiosError
|
||||||
axios.isAxiosError = require('./helpers/isAxiosError');
|
axios.isAxiosError = require('./helpers/isAxiosError');
|
||||||
|
|
||||||
|
axios.formToJSON = function(thing) {
|
||||||
|
return formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = axios;
|
module.exports = axios;
|
||||||
|
|
||||||
// Allow use of default import syntax in TypeScript
|
// Allow use of default import syntax in TypeScript
|
||||||
|
|||||||
+2
-1
@@ -25,7 +25,8 @@ function Axios(instanceConfig) {
|
|||||||
/**
|
/**
|
||||||
* Dispatch a request
|
* Dispatch a request
|
||||||
*
|
*
|
||||||
* @param {Object} config The config specific for this request (merged with this.defaults)
|
* @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults)
|
||||||
|
* @param {?Object} config
|
||||||
*/
|
*/
|
||||||
Axios.prototype.request = function request(configOrUrl, config) {
|
Axios.prototype.request = function request(configOrUrl, config) {
|
||||||
/*eslint no-param-reassign:0*/
|
/*eslint no-param-reassign:0*/
|
||||||
|
|||||||
+21
-6
@@ -7,6 +7,7 @@ var transitionalDefaults = require('./transitional');
|
|||||||
var toFormData = require('../helpers/toFormData');
|
var toFormData = require('../helpers/toFormData');
|
||||||
var toURLEncodedForm = require('../helpers/toURLEncodedForm');
|
var toURLEncodedForm = require('../helpers/toURLEncodedForm');
|
||||||
var platform = require('../platform');
|
var platform = require('../platform');
|
||||||
|
var formDataToJSON = require('../helpers/formDataToJSON');
|
||||||
|
|
||||||
var DEFAULT_CONTENT_TYPE = {
|
var DEFAULT_CONTENT_TYPE = {
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
@@ -55,8 +56,24 @@ var defaults = {
|
|||||||
normalizeHeaderName(headers, 'Accept');
|
normalizeHeaderName(headers, 'Accept');
|
||||||
normalizeHeaderName(headers, 'Content-Type');
|
normalizeHeaderName(headers, 'Content-Type');
|
||||||
|
|
||||||
if (utils.isFormData(data) ||
|
var contentType = headers && headers['Content-Type'] || '';
|
||||||
utils.isArrayBuffer(data) ||
|
var hasJSONContentType = contentType.indexOf('application/json') > -1;
|
||||||
|
var isObjectPayload = utils.isObject(data);
|
||||||
|
|
||||||
|
if (isObjectPayload && utils.isHTMLForm(data)) {
|
||||||
|
data = new FormData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
var isFormData = utils.isFormData(data);
|
||||||
|
|
||||||
|
if (isFormData) {
|
||||||
|
if (!hasJSONContentType) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (utils.isArrayBuffer(data) ||
|
||||||
utils.isBuffer(data) ||
|
utils.isBuffer(data) ||
|
||||||
utils.isStream(data) ||
|
utils.isStream(data) ||
|
||||||
utils.isFile(data) ||
|
utils.isFile(data) ||
|
||||||
@@ -72,8 +89,6 @@ var defaults = {
|
|||||||
return data.toString();
|
return data.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
var isObjectPayload = utils.isObject(data);
|
|
||||||
var contentType = headers && headers['Content-Type'] || '';
|
|
||||||
var isFileList;
|
var isFileList;
|
||||||
|
|
||||||
if (isObjectPayload) {
|
if (isObjectPayload) {
|
||||||
@@ -81,7 +96,7 @@ var defaults = {
|
|||||||
return toURLEncodedForm(data, this.formSerializer).toString();
|
return toURLEncodedForm(data, this.formSerializer).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((isFileList = utils.isFileList(data)) || contentType.indexOf('multipart/form-data') !== -1) {
|
if ((isFileList = utils.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) {
|
||||||
var _FormData = this.env && this.env.FormData;
|
var _FormData = this.env && this.env.FormData;
|
||||||
|
|
||||||
return toFormData(
|
return toFormData(
|
||||||
@@ -92,7 +107,7 @@ var defaults = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isObjectPayload || contentType.indexOf('application/json') !== -1) {
|
if (isObjectPayload || hasJSONContentType ) {
|
||||||
setContentTypeIfUnset(headers, 'application/json');
|
setContentTypeIfUnset(headers, 'application/json');
|
||||||
return stringifySafely(data);
|
return stringifySafely(data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var utils = require('../utils');
|
||||||
|
|
||||||
|
function parsePropPath(name) {
|
||||||
|
// foo[x][y][z]
|
||||||
|
// foo.x.y.z
|
||||||
|
// foo-x-y-z
|
||||||
|
// foo x y z
|
||||||
|
return utils.matchAll(/\w+|\[(\w*)]/g, name).map(function(match) {
|
||||||
|
return match[0] === '[]' ? '' : match[1] || match[0];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function arrayToObject(arr) {
|
||||||
|
var obj = {};
|
||||||
|
var keys = Object.keys(arr);
|
||||||
|
var i;
|
||||||
|
var len = keys.length;
|
||||||
|
var key;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
key = keys[i];
|
||||||
|
obj[key] = arr[key];
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formDataToJSON(formData) {
|
||||||
|
function buildPath(path, value, target, index) {
|
||||||
|
var name = path[index++];
|
||||||
|
var isNumericKey = Number.isFinite(+name);
|
||||||
|
var isLast = index >= path.length;
|
||||||
|
name = !name && utils.isArray(target) ? target.length : name;
|
||||||
|
|
||||||
|
if (isLast) {
|
||||||
|
if (utils.hasOwnProperty(target, name)) {
|
||||||
|
target[name] = [target[name], value];
|
||||||
|
} else {
|
||||||
|
target[name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !isNumericKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!target[name] || !utils.isObject(target[name])) {
|
||||||
|
target[name] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = buildPath(path, value, target[name], index);
|
||||||
|
|
||||||
|
if (result && utils.isArray(target[name])) {
|
||||||
|
target[name] = arrayToObject(target[name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !isNumericKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (utils.isFormData(formData) && utils.isFunction(formData.entries)) {
|
||||||
|
var obj = {};
|
||||||
|
|
||||||
|
utils.forEachEntry(formData, function(name, value) {
|
||||||
|
buildPath(parsePropPath(name), value, obj, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = formDataToJSON;
|
||||||
+37
-1
@@ -441,6 +441,38 @@ var isTypedArray = (function(TypedArray) {
|
|||||||
};
|
};
|
||||||
})(typeof Uint8Array !== 'undefined' && Object.getPrototypeOf(Uint8Array));
|
})(typeof Uint8Array !== 'undefined' && Object.getPrototypeOf(Uint8Array));
|
||||||
|
|
||||||
|
function forEachEntry(obj, fn) {
|
||||||
|
var generator = obj && obj[Symbol.iterator];
|
||||||
|
|
||||||
|
var iterator = generator.call(obj);
|
||||||
|
|
||||||
|
var result;
|
||||||
|
|
||||||
|
while ((result = iterator.next()) && !result.done) {
|
||||||
|
var pair = result.value;
|
||||||
|
fn.call(obj, pair[0], pair[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function matchAll(regExp, str) {
|
||||||
|
var matches;
|
||||||
|
var arr = [];
|
||||||
|
|
||||||
|
while ((matches = regExp.exec(str)) !== null) {
|
||||||
|
arr.push(matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
var isHTMLForm = kindOfTest('HTMLFormElement');
|
||||||
|
|
||||||
|
var hasOwnProperty = (function resolver(_hasOwnProperty) {
|
||||||
|
return function(obj, prop) {
|
||||||
|
return _hasOwnProperty.call(obj, prop);
|
||||||
|
};
|
||||||
|
})(Object.prototype.hasOwnProperty);
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
isArray: isArray,
|
isArray: isArray,
|
||||||
isArrayBuffer: isArrayBuffer,
|
isArrayBuffer: isArrayBuffer,
|
||||||
@@ -471,5 +503,9 @@ module.exports = {
|
|||||||
endsWith: endsWith,
|
endsWith: endsWith,
|
||||||
toArray: toArray,
|
toArray: toArray,
|
||||||
isTypedArray: isTypedArray,
|
isTypedArray: isTypedArray,
|
||||||
isFileList: isFileList
|
isFileList: isFileList,
|
||||||
|
forEachEntry: forEachEntry,
|
||||||
|
matchAll: matchAll,
|
||||||
|
isHTMLForm: isHTMLForm,
|
||||||
|
hasOwnProperty: hasOwnProperty
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
var formDataToJSON = require('../../../lib/helpers/formDataToJSON');
|
||||||
|
|
||||||
|
describe('formDataToJSON', function () {
|
||||||
|
it('should convert a FormData Object to JSON Object', function () {
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
formData.append('foo[bar][baz]', '123');
|
||||||
|
|
||||||
|
expect(formDataToJSON(formData)).toEqual({
|
||||||
|
foo: {
|
||||||
|
bar: {
|
||||||
|
baz: '123'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should convert repeatable values as an array', function () {
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
formData.append('foo', '1');
|
||||||
|
formData.append('foo', '2');
|
||||||
|
|
||||||
|
expect(formDataToJSON(formData)).toEqual({
|
||||||
|
foo: ['1', '2']
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should convert props with empty brackets to arrays', function () {
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
formData.append('foo[]', '1');
|
||||||
|
formData.append('foo[]', '2');
|
||||||
|
|
||||||
|
expect(formDataToJSON(formData)).toEqual({
|
||||||
|
foo: ['1', '2']
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should supported indexed arrays', function () {
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
formData.append('foo[0]', '1');
|
||||||
|
formData.append('foo[1]', '2');
|
||||||
|
|
||||||
|
expect(formDataToJSON(formData)).toEqual({
|
||||||
|
foo: ['1', '2']
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -25,7 +25,8 @@ describe('instance', function () {
|
|||||||
'isAxiosError',
|
'isAxiosError',
|
||||||
'VERSION',
|
'VERSION',
|
||||||
'default',
|
'default',
|
||||||
'toFormData'
|
'toFormData',
|
||||||
|
'formToJSON'
|
||||||
].indexOf(prop) > -1) {
|
].indexOf(prop) > -1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user