From cc86c6c49fdbfd8e2517b191b8833d2f2816ff91 Mon Sep 17 00:00:00 2001 From: Jay Date: Thu, 27 Jan 2022 08:39:25 +0200 Subject: [PATCH 1/4] Fix/remove url required (#4426) * Removed error when url is null as this breaks current use cases for alot of projects * Removed associated tests that check for the for url to not be empty --- lib/core/Axios.js | 7 ------- test/specs/requests.spec.js | 18 ------------------ 2 files changed, 25 deletions(-) diff --git a/lib/core/Axios.js b/lib/core/Axios.js index d7ce7db..a1be08a 100644 --- a/lib/core/Axios.js +++ b/lib/core/Axios.js @@ -36,10 +36,6 @@ Axios.prototype.request = function request(configOrUrl, config) { config = configOrUrl || {}; } - if (!config.url) { - throw new Error('Provided config url is not valid'); - } - config = mergeConfig(this.defaults, config); // Set config.method @@ -122,9 +118,6 @@ Axios.prototype.request = function request(configOrUrl, config) { }; Axios.prototype.getUri = function getUri(config) { - if (!config.url) { - throw new Error('Provided config url is not valid'); - } config = mergeConfig(this.defaults, config); return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\?/, ''); }; diff --git a/test/specs/requests.spec.js b/test/specs/requests.spec.js index e363fef..a5aa81a 100644 --- a/test/specs/requests.spec.js +++ b/test/specs/requests.spec.js @@ -7,24 +7,6 @@ describe('requests', function () { jasmine.Ajax.uninstall(); }); - it('should throw error when missing url', function (done) { - expect(() => axios()).toThrowError(/Provided config url is not valid/); - done(); - - expect(() => axios('')).toThrowError(/Provided config url is not valid/); - done(); - - expect(() => axios({ - url: undefined, - })).toThrowError(/Provided config url is not valid/); - done(); - - expect(() => axios({ - method: 'POST', - })).toThrowError(/Provided config url is not valid/); - done(); - }); - it('should treat single string arg as url', function (done) { axios('/foo'); From 73e3bdb8835ba942096b662e9441f1d85ce4d484 Mon Sep 17 00:00:00 2001 From: Dmitriy Mozgovoy Date: Wed, 2 Feb 2022 13:48:44 +0200 Subject: [PATCH 2/4] Fixed isFormData predicate; (#4413) Added support for automatic object serialization to FormData if `Content-Type` is `multipart/form-data`; Added support for FormData to be overloaded using `config.env.FormData` option; Added support for FormData in node.js environment through `form-data` package; --- index.d.ts | 3 +++ lib/adapters/http.js | 4 +++- lib/defaults.js | 12 +++++++++++- lib/helpers/toFormData.js | 10 +++++++--- lib/utils.js | 24 +++++++++++++++--------- test/specs/helpers/toFormData.spec.js | 2 +- 6 files changed, 40 insertions(+), 15 deletions(-) diff --git a/index.d.ts b/index.d.ts index b681915..5cb94c5 100644 --- a/index.d.ts +++ b/index.d.ts @@ -107,6 +107,9 @@ export interface AxiosRequestConfig { transitional?: TransitionalOptions; signal?: AbortSignal; insecureHTTPParser?: boolean; + env?: { + FormData?: new (...args: any[]) => object; + }; } export interface HeadersDefaults { diff --git a/lib/adapters/http.js b/lib/adapters/http.js index 951e400..5753fbd 100755 --- a/lib/adapters/http.js +++ b/lib/adapters/http.js @@ -87,7 +87,9 @@ module.exports = function httpAdapter(config) { headers['User-Agent'] = 'axios/' + VERSION; } - if (data && !utils.isStream(data)) { + if (utils.isFormData(data) && utils.isFunction(data.getHeaders)) { + Object.assign(headers, data.getHeaders()); + } else if (data && !utils.isStream(data)) { if (Buffer.isBuffer(data)) { // Nothing to do... } else if (utils.isArrayBuffer(data)) { diff --git a/lib/defaults.js b/lib/defaults.js index eaee189..cb061af 100644 --- a/lib/defaults.js +++ b/lib/defaults.js @@ -3,6 +3,7 @@ var utils = require('./utils'); var normalizeHeaderName = require('./helpers/normalizeHeaderName'); var enhanceError = require('./core/enhanceError'); +var toFormData = require('./helpers/toFormData'); var DEFAULT_CONTENT_TYPE = { 'Content-Type': 'application/x-www-form-urlencoded' @@ -71,10 +72,17 @@ var defaults = { setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8'); return data.toString(); } - if (utils.isObject(data) || (headers && headers['Content-Type'] === 'application/json')) { + + var isObjectPayload = utils.isObject(data); + var contentType = headers && headers['Content-Type']; + + if ( isObjectPayload && contentType === 'multipart/form-data' ) { + return toFormData(data, new (this.env && this.env.FormData || FormData)); + } else if ( isObjectPayload || contentType === 'application/json' ) { setContentTypeIfUnset(headers, 'application/json'); return stringifySafely(data); } + return data; }], @@ -112,6 +120,8 @@ var defaults = { maxContentLength: -1, maxBodyLength: -1, + env: {}, + validateStatus: function validateStatus(status) { return status >= 200 && status < 300; }, diff --git a/lib/helpers/toFormData.js b/lib/helpers/toFormData.js index e21d0a7..0f03b79 100644 --- a/lib/helpers/toFormData.js +++ b/lib/helpers/toFormData.js @@ -1,5 +1,7 @@ 'use strict'; +var utils = require('../utils'); + function combinedKey(parentKey, elKey) { return parentKey + '.' + elKey; } @@ -11,7 +13,7 @@ function buildFormData(formData, data, parentKey) { }); } else if ( typeof data === 'object' && - !(data instanceof File || data === null) + !(utils.isFile(data) || data === null) ) { Object.keys(data).forEach(function buildObject(key) { buildFormData( @@ -44,10 +46,12 @@ function buildFormData(formData, data, parentKey) { * type FormVal = FormDataNest | FormDataPrimitive * * @param {FormVal} data + * @param {?Object} formData */ -module.exports = function getFormData(data) { - var formData = new FormData(); +module.exports = function getFormData(data, formData) { + // eslint-disable-next-line no-param-reassign + formData = formData || new FormData(); buildFormData(formData, data); diff --git a/lib/utils.js b/lib/utils.js index f0f9043..536fbf9 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -47,15 +47,6 @@ function isArrayBuffer(val) { return toString.call(val) === '[object ArrayBuffer]'; } -/** - * Determine if a value is a FormData - * - * @param {Object} val The value to test - * @returns {boolean} True if value is an FormData, otherwise false - */ -function isFormData(val) { - return toString.call(val) === '[object FormData]'; -} /** * Determine if a value is a view on an ArrayBuffer @@ -168,6 +159,21 @@ function isStream(val) { return isObject(val) && isFunction(val.pipe); } +/** + * Determine if a value is a FormData + * + * @param {Object} thing The value to test + * @returns {boolean} True if value is an FormData, otherwise false + */ +function isFormData(thing) { + var pattern = '[object FormData]'; + return thing && ( + (typeof FormData === 'function' && thing instanceof FormData) || + toString.call(thing) === pattern || + (isFunction(thing.toString) && thing.toString() === pattern) + ); +} + /** * Determine if a value is a URLSearchParams object * diff --git a/test/specs/helpers/toFormData.spec.js b/test/specs/helpers/toFormData.spec.js index f28471e..ec16252 100644 --- a/test/specs/helpers/toFormData.spec.js +++ b/test/specs/helpers/toFormData.spec.js @@ -1,7 +1,7 @@ var toFormData = require("../../../lib/helpers/toFormData"); describe("toFormData", function () { - it("Convert nested data object to FormDAta", function () { + it("Convert nested data object to FormData", function () { var o = { val: 123, nested: { From c5bdbd436d7ac90d7bac26247cb60752d171e47c Mon Sep 17 00:00:00 2001 From: CookieMr Date: Fri, 11 Feb 2022 14:55:10 +0100 Subject: [PATCH 3/4] Update follow-redirects dependency due to Vurnerbility Previous version of follow-redirects dependency is reported by Snyk to have a vurnerbility. https://app.snyk.io/test/npm/follow-redirects/1.14.7 --- README.md | 1 + package-lock.json | 18 +++++++++--------- package.json | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index d409c79..d5ba7f9 100755 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ [![npm downloads](https://img.shields.io/npm/dm/axios.svg?style=flat-square)](http://npm-stat.com/charts.html?package=axios) [![gitter chat](https://img.shields.io/gitter/room/mzabriskie/axios.svg?style=flat-square)](https://gitter.im/mzabriskie/axios) [![code helpers](https://www.codetriage.com/axios/axios/badges/users.svg)](https://www.codetriage.com/axios/axios) +[![Known Vulnerabilities](https://snyk.io/test/npm/axios/badge.svg)](https://snyk.io/test/npm/axios) Promise based HTTP client for the browser and node.js diff --git a/package-lock.json b/package-lock.json index 514eca9..7ca6920 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,14 @@ { "name": "axios", - "version": "0.24.0", + "version": "0.25.1", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "0.24.0", + "version": "0.25.1", "license": "MIT", "dependencies": { - "follow-redirects": "^1.14.7" + "follow-redirects": "^1.14.8" }, "devDependencies": { "abortcontroller-polyfill": "^1.5.0", @@ -5603,9 +5603,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.14.7", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", - "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==", + "version": "1.14.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", + "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==", "funding": [ { "type": "individual", @@ -20841,9 +20841,9 @@ } }, "follow-redirects": { - "version": "1.14.7", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", - "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==" + "version": "1.14.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", + "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==" }, "for-in": { "version": "1.0.2", diff --git a/package.json b/package.json index 6215a00..e7c75a3 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "unpkg": "dist/axios.min.js", "typings": "./index.d.ts", "dependencies": { - "follow-redirects": "^1.14.7" + "follow-redirects": "^1.14.8" }, "bundlesize": [ { From 95295f6f291fc7e647e8d3c2960b5d26a2df707d Mon Sep 17 00:00:00 2001 From: Jay Date: Sun, 13 Feb 2022 15:55:42 +0200 Subject: [PATCH 4/4] Fixed conflict in package lock --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7ca6920..1f824df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { "name": "axios", - "version": "0.25.1", + "version": "0.25.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "0.25.1", + "version": "0.25.0", "license": "MIT", "dependencies": { "follow-redirects": "^1.14.8"