axios 1.7.9 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +200 -0
- package/README.md +62 -37
- package/dist/axios.js +438 -327
- package/dist/axios.js.map +1 -1
- package/dist/axios.min.js +2 -1
- package/dist/axios.min.js.map +1 -1
- package/dist/browser/axios.cjs +369 -249
- package/dist/browser/axios.cjs.map +1 -1
- package/dist/esm/axios.js +369 -249
- package/dist/esm/axios.js.map +1 -1
- package/dist/esm/axios.min.js +2 -1
- package/dist/esm/axios.min.js.map +1 -1
- package/dist/node/axios.cjs +491 -253
- package/dist/node/axios.cjs.map +1 -1
- package/index.d.cts +26 -10
- package/index.d.ts +16 -7
- package/lib/adapters/adapters.js +6 -4
- package/lib/adapters/fetch.js +220 -163
- package/lib/adapters/http.js +19 -1
- package/lib/adapters/xhr.js +11 -8
- package/lib/core/Axios.js +13 -4
- package/lib/core/AxiosError.js +10 -3
- package/lib/core/AxiosHeaders.js +15 -3
- package/lib/core/buildFullPath.js +3 -2
- package/lib/core/dispatchRequest.js +1 -1
- package/lib/core/mergeConfig.js +1 -1
- package/lib/defaults/index.js +1 -1
- package/lib/env/data.js +1 -1
- package/lib/helpers/buildURL.js +1 -3
- package/lib/helpers/estimateDataURLDecodedBytes.js +73 -0
- package/lib/helpers/formDataToStream.js +4 -3
- package/lib/helpers/resolveConfig.js +14 -10
- package/lib/helpers/throttle.js +1 -1
- package/lib/helpers/toFormData.js +4 -0
- package/lib/helpers/toURLEncodedForm.js +4 -3
- package/lib/platform/node/index.js +26 -0
- package/lib/utils.js +52 -28
- package/package.json +24 -12
- package/SECURITY.md +0 -6
package/lib/adapters/fetch.js
CHANGED
|
@@ -8,14 +8,18 @@ import {progressEventReducer, progressEventDecorator, asyncDecorator} from "../h
|
|
|
8
8
|
import resolveConfig from "../helpers/resolveConfig.js";
|
|
9
9
|
import settle from "../core/settle.js";
|
|
10
10
|
|
|
11
|
-
const
|
|
12
|
-
|
|
11
|
+
const DEFAULT_CHUNK_SIZE = 64 * 1024;
|
|
12
|
+
|
|
13
|
+
const {isFunction} = utils;
|
|
14
|
+
|
|
15
|
+
const globalFetchAPI = (({fetch, Request, Response}) => ({
|
|
16
|
+
fetch, Request, Response
|
|
17
|
+
}))(utils.global);
|
|
18
|
+
|
|
19
|
+
const {
|
|
20
|
+
ReadableStream, TextEncoder
|
|
21
|
+
} = utils.global;
|
|
13
22
|
|
|
14
|
-
// used only inside the fetch adapter
|
|
15
|
-
const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ?
|
|
16
|
-
((encoder) => (str) => encoder.encode(str))(new TextEncoder()) :
|
|
17
|
-
async (str) => new Uint8Array(await new Response(str).arrayBuffer())
|
|
18
|
-
);
|
|
19
23
|
|
|
20
24
|
const test = (fn, ...args) => {
|
|
21
25
|
try {
|
|
@@ -25,205 +29,258 @@ const test = (fn, ...args) => {
|
|
|
25
29
|
}
|
|
26
30
|
}
|
|
27
31
|
|
|
28
|
-
const
|
|
29
|
-
|
|
32
|
+
const factory = (env) => {
|
|
33
|
+
const {fetch, Request, Response} = Object.assign({}, globalFetchAPI, env);
|
|
34
|
+
const isFetchSupported = isFunction(fetch);
|
|
35
|
+
const isRequestSupported = isFunction(Request);
|
|
36
|
+
const isResponseSupported = isFunction(Response);
|
|
30
37
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
get duplex() {
|
|
35
|
-
duplexAccessed = true;
|
|
36
|
-
return 'half';
|
|
37
|
-
},
|
|
38
|
-
}).headers.has('Content-Type');
|
|
38
|
+
if (!isFetchSupported) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
});
|
|
42
|
+
const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream);
|
|
42
43
|
|
|
43
|
-
const
|
|
44
|
+
const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ?
|
|
45
|
+
((encoder) => (str) => encoder.encode(str))(new TextEncoder()) :
|
|
46
|
+
async (str) => new Uint8Array(await new Request(str).arrayBuffer())
|
|
47
|
+
);
|
|
44
48
|
|
|
45
|
-
const
|
|
46
|
-
|
|
49
|
+
const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => {
|
|
50
|
+
let duplexAccessed = false;
|
|
47
51
|
|
|
52
|
+
const hasContentType = new Request(platform.origin, {
|
|
53
|
+
body: new ReadableStream(),
|
|
54
|
+
method: 'POST',
|
|
55
|
+
get duplex() {
|
|
56
|
+
duplexAccessed = true;
|
|
57
|
+
return 'half';
|
|
58
|
+
},
|
|
59
|
+
}).headers.has('Content-Type');
|
|
48
60
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
61
|
+
return duplexAccessed && !hasContentType;
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const supportsResponseStream = isResponseSupported && isReadableStreamSupported &&
|
|
65
|
+
test(() => utils.isReadableStream(new Response('').body));
|
|
66
|
+
|
|
67
|
+
const resolvers = {
|
|
68
|
+
stream: supportsResponseStream && ((res) => res.body)
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
isFetchSupported && ((() => {
|
|
72
|
+
['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => {
|
|
73
|
+
!resolvers[type] && (resolvers[type] = (res, config) => {
|
|
74
|
+
let method = res && res[type];
|
|
75
|
+
|
|
76
|
+
if (method) {
|
|
77
|
+
return method.call(res);
|
|
78
|
+
}
|
|
52
79
|
|
|
53
|
-
isFetchSupported && (((res) => {
|
|
54
|
-
['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => {
|
|
55
|
-
!resolvers[type] && (resolvers[type] = utils.isFunction(res[type]) ? (res) => res[type]() :
|
|
56
|
-
(_, config) => {
|
|
57
80
|
throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config);
|
|
58
81
|
})
|
|
59
|
-
|
|
60
|
-
})(
|
|
82
|
+
});
|
|
83
|
+
})());
|
|
61
84
|
|
|
62
|
-
const getBodyLength = async (body) => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
85
|
+
const getBodyLength = async (body) => {
|
|
86
|
+
if (body == null) {
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
66
89
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
90
|
+
if (utils.isBlob(body)) {
|
|
91
|
+
return body.size;
|
|
92
|
+
}
|
|
70
93
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
94
|
+
if (utils.isSpecCompliantForm(body)) {
|
|
95
|
+
const _request = new Request(platform.origin, {
|
|
96
|
+
method: 'POST',
|
|
97
|
+
body,
|
|
98
|
+
});
|
|
99
|
+
return (await _request.arrayBuffer()).byteLength;
|
|
100
|
+
}
|
|
78
101
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
102
|
+
if (utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) {
|
|
103
|
+
return body.byteLength;
|
|
104
|
+
}
|
|
82
105
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
106
|
+
if (utils.isURLSearchParams(body)) {
|
|
107
|
+
body = body + '';
|
|
108
|
+
}
|
|
86
109
|
|
|
87
|
-
|
|
88
|
-
|
|
110
|
+
if (utils.isString(body)) {
|
|
111
|
+
return (await encodeText(body)).byteLength;
|
|
112
|
+
}
|
|
89
113
|
}
|
|
90
|
-
}
|
|
91
114
|
|
|
92
|
-
const resolveBodyLength = async (headers, body) => {
|
|
93
|
-
|
|
115
|
+
const resolveBodyLength = async (headers, body) => {
|
|
116
|
+
const length = utils.toFiniteNumber(headers.getContentLength());
|
|
94
117
|
|
|
95
|
-
|
|
96
|
-
}
|
|
118
|
+
return length == null ? getBodyLength(body) : length;
|
|
119
|
+
}
|
|
97
120
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
return async (config) => {
|
|
122
|
+
let {
|
|
123
|
+
url,
|
|
124
|
+
method,
|
|
125
|
+
data,
|
|
126
|
+
signal,
|
|
127
|
+
cancelToken,
|
|
128
|
+
timeout,
|
|
129
|
+
onDownloadProgress,
|
|
130
|
+
onUploadProgress,
|
|
131
|
+
responseType,
|
|
132
|
+
headers,
|
|
133
|
+
withCredentials = 'same-origin',
|
|
134
|
+
fetchOptions
|
|
135
|
+
} = resolveConfig(config);
|
|
136
|
+
|
|
137
|
+
responseType = responseType ? (responseType + '').toLowerCase() : 'text';
|
|
138
|
+
|
|
139
|
+
let composedSignal = composeSignals([signal, cancelToken && cancelToken.toAbortSignal()], timeout);
|
|
140
|
+
|
|
141
|
+
let request = null;
|
|
142
|
+
|
|
143
|
+
const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {
|
|
121
144
|
composedSignal.unsubscribe();
|
|
122
|
-
|
|
145
|
+
});
|
|
123
146
|
|
|
124
|
-
|
|
147
|
+
let requestContentLength;
|
|
125
148
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
149
|
+
try {
|
|
150
|
+
if (
|
|
151
|
+
onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' &&
|
|
152
|
+
(requestContentLength = await resolveBodyLength(headers, data)) !== 0
|
|
153
|
+
) {
|
|
154
|
+
let _request = new Request(url, {
|
|
155
|
+
method: 'POST',
|
|
156
|
+
body: data,
|
|
157
|
+
duplex: "half"
|
|
158
|
+
});
|
|
136
159
|
|
|
137
|
-
|
|
160
|
+
let contentTypeHeader;
|
|
138
161
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
162
|
+
if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {
|
|
163
|
+
headers.setContentType(contentTypeHeader)
|
|
164
|
+
}
|
|
142
165
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
166
|
+
if (_request.body) {
|
|
167
|
+
const [onProgress, flush] = progressEventDecorator(
|
|
168
|
+
requestContentLength,
|
|
169
|
+
progressEventReducer(asyncDecorator(onUploadProgress))
|
|
170
|
+
);
|
|
148
171
|
|
|
149
|
-
|
|
172
|
+
data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);
|
|
173
|
+
}
|
|
150
174
|
}
|
|
151
|
-
}
|
|
152
175
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
176
|
+
if (!utils.isString(withCredentials)) {
|
|
177
|
+
withCredentials = withCredentials ? 'include' : 'omit';
|
|
178
|
+
}
|
|
156
179
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
request = new Request(url, {
|
|
161
|
-
...fetchOptions,
|
|
162
|
-
signal: composedSignal,
|
|
163
|
-
method: method.toUpperCase(),
|
|
164
|
-
headers: headers.normalize().toJSON(),
|
|
165
|
-
body: data,
|
|
166
|
-
duplex: "half",
|
|
167
|
-
credentials: isCredentialsSupported ? withCredentials : undefined
|
|
168
|
-
});
|
|
180
|
+
// Cloudflare Workers throws when credentials are defined
|
|
181
|
+
// see https://github.com/cloudflare/workerd/issues/902
|
|
182
|
+
const isCredentialsSupported = isRequestSupported && "credentials" in Request.prototype;
|
|
169
183
|
|
|
170
|
-
|
|
184
|
+
const resolvedOptions = {
|
|
185
|
+
...fetchOptions,
|
|
186
|
+
signal: composedSignal,
|
|
187
|
+
method: method.toUpperCase(),
|
|
188
|
+
headers: headers.normalize().toJSON(),
|
|
189
|
+
body: data,
|
|
190
|
+
duplex: "half",
|
|
191
|
+
credentials: isCredentialsSupported ? withCredentials : undefined
|
|
192
|
+
};
|
|
171
193
|
|
|
172
|
-
|
|
194
|
+
request = isRequestSupported && new Request(url, resolvedOptions);
|
|
173
195
|
|
|
174
|
-
|
|
175
|
-
const options = {};
|
|
196
|
+
let response = await (isRequestSupported ? fetch(request, fetchOptions) : fetch(url, resolvedOptions));
|
|
176
197
|
|
|
177
|
-
|
|
178
|
-
options[prop] = response[prop];
|
|
179
|
-
});
|
|
198
|
+
const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response');
|
|
180
199
|
|
|
181
|
-
|
|
200
|
+
if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) {
|
|
201
|
+
const options = {};
|
|
182
202
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
) || [];
|
|
203
|
+
['status', 'statusText', 'headers'].forEach(prop => {
|
|
204
|
+
options[prop] = response[prop];
|
|
205
|
+
});
|
|
187
206
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
);
|
|
195
|
-
}
|
|
207
|
+
const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length'));
|
|
208
|
+
|
|
209
|
+
const [onProgress, flush] = onDownloadProgress && progressEventDecorator(
|
|
210
|
+
responseContentLength,
|
|
211
|
+
progressEventReducer(asyncDecorator(onDownloadProgress), true)
|
|
212
|
+
) || [];
|
|
196
213
|
|
|
197
|
-
|
|
214
|
+
response = new Response(
|
|
215
|
+
trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {
|
|
216
|
+
flush && flush();
|
|
217
|
+
unsubscribe && unsubscribe();
|
|
218
|
+
}),
|
|
219
|
+
options
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
responseType = responseType || 'text';
|
|
198
224
|
|
|
199
|
-
|
|
225
|
+
let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text'](response, config);
|
|
200
226
|
|
|
201
|
-
|
|
227
|
+
!isStreamResponse && unsubscribe && unsubscribe();
|
|
202
228
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
229
|
+
return await new Promise((resolve, reject) => {
|
|
230
|
+
settle(resolve, reject, {
|
|
231
|
+
data: responseData,
|
|
232
|
+
headers: AxiosHeaders.from(response.headers),
|
|
233
|
+
status: response.status,
|
|
234
|
+
statusText: response.statusText,
|
|
235
|
+
config,
|
|
236
|
+
request
|
|
237
|
+
})
|
|
211
238
|
})
|
|
212
|
-
})
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
239
|
+
} catch (err) {
|
|
240
|
+
unsubscribe && unsubscribe();
|
|
241
|
+
|
|
242
|
+
if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {
|
|
243
|
+
throw Object.assign(
|
|
244
|
+
new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request),
|
|
245
|
+
{
|
|
246
|
+
cause: err.cause || err
|
|
247
|
+
}
|
|
248
|
+
)
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
throw AxiosError.from(err, err && err.code, config, request);
|
|
223
252
|
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const seedCache = new Map();
|
|
224
257
|
|
|
225
|
-
|
|
258
|
+
export const getFetch = (config) => {
|
|
259
|
+
let env = utils.merge.call({
|
|
260
|
+
skipUndefined: true
|
|
261
|
+
}, globalFetchAPI, config ? config.env : null);
|
|
262
|
+
|
|
263
|
+
const {fetch, Request, Response} = env;
|
|
264
|
+
|
|
265
|
+
const seeds = [
|
|
266
|
+
Request, Response, fetch
|
|
267
|
+
];
|
|
268
|
+
|
|
269
|
+
let len = seeds.length, i = len,
|
|
270
|
+
seed, target, map = seedCache;
|
|
271
|
+
|
|
272
|
+
while (i--) {
|
|
273
|
+
seed = seeds[i];
|
|
274
|
+
target = map.get(seed);
|
|
275
|
+
|
|
276
|
+
target === undefined && map.set(seed, target = (i ? new Map() : factory(env)))
|
|
277
|
+
|
|
278
|
+
map = target;
|
|
226
279
|
}
|
|
227
|
-
});
|
|
228
280
|
|
|
281
|
+
return target;
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
const adapter = getFetch();
|
|
229
285
|
|
|
286
|
+
export default adapter;
|
package/lib/adapters/http.js
CHANGED
|
@@ -25,6 +25,7 @@ import readBlob from "../helpers/readBlob.js";
|
|
|
25
25
|
import ZlibHeaderTransformStream from '../helpers/ZlibHeaderTransformStream.js';
|
|
26
26
|
import callbackify from "../helpers/callbackify.js";
|
|
27
27
|
import {progressEventReducer, progressEventDecorator, asyncDecorator} from "../helpers/progressEventReducer.js";
|
|
28
|
+
import estimateDataURLDecodedBytes from '../helpers/estimateDataURLDecodedBytes.js';
|
|
28
29
|
|
|
29
30
|
const zlibOptions = {
|
|
30
31
|
flush: zlib.constants.Z_SYNC_FLUSH,
|
|
@@ -46,6 +47,7 @@ const supportedProtocols = platform.protocols.map(protocol => {
|
|
|
46
47
|
return protocol + ':';
|
|
47
48
|
});
|
|
48
49
|
|
|
50
|
+
|
|
49
51
|
const flushOnFinish = (stream, [throttled, flush]) => {
|
|
50
52
|
stream
|
|
51
53
|
.on('end', flush)
|
|
@@ -54,6 +56,7 @@ const flushOnFinish = (stream, [throttled, flush]) => {
|
|
|
54
56
|
return throttled;
|
|
55
57
|
}
|
|
56
58
|
|
|
59
|
+
|
|
57
60
|
/**
|
|
58
61
|
* If the proxy or config beforeRedirects functions are defined, call them with the options
|
|
59
62
|
* object.
|
|
@@ -228,11 +231,26 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
|
|
|
228
231
|
}
|
|
229
232
|
|
|
230
233
|
// Parse url
|
|
231
|
-
const fullPath = buildFullPath(config.baseURL, config.url);
|
|
234
|
+
const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
|
|
232
235
|
const parsed = new URL(fullPath, platform.hasBrowserEnv ? platform.origin : undefined);
|
|
233
236
|
const protocol = parsed.protocol || supportedProtocols[0];
|
|
234
237
|
|
|
235
238
|
if (protocol === 'data:') {
|
|
239
|
+
// Apply the same semantics as HTTP: only enforce if a finite, non-negative cap is set.
|
|
240
|
+
if (config.maxContentLength > -1) {
|
|
241
|
+
// Use the exact string passed to fromDataURI (config.url); fall back to fullPath if needed.
|
|
242
|
+
const dataUrl = String(config.url || fullPath || '');
|
|
243
|
+
const estimated = estimateDataURLDecodedBytes(dataUrl);
|
|
244
|
+
|
|
245
|
+
if (estimated > config.maxContentLength) {
|
|
246
|
+
return reject(new AxiosError(
|
|
247
|
+
'maxContentLength size of ' + config.maxContentLength + ' exceeded',
|
|
248
|
+
AxiosError.ERR_BAD_RESPONSE,
|
|
249
|
+
config
|
|
250
|
+
));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
236
254
|
let convertedData;
|
|
237
255
|
|
|
238
256
|
if (method !== 'GET') {
|
package/lib/adapters/xhr.js
CHANGED
|
@@ -104,15 +104,18 @@ export default isXHRAdapterSupported && function (config) {
|
|
|
104
104
|
};
|
|
105
105
|
|
|
106
106
|
// Handle low level network errors
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
107
|
+
request.onerror = function handleError(event) {
|
|
108
|
+
// Browsers deliver a ProgressEvent in XHR onerror
|
|
109
|
+
// (message may be empty; when present, surface it)
|
|
110
|
+
// See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event
|
|
111
|
+
const msg = event && event.message ? event.message : 'Network Error';
|
|
112
|
+
const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request);
|
|
113
|
+
// attach the underlying event for consumers who want details
|
|
114
|
+
err.event = event || null;
|
|
115
|
+
reject(err);
|
|
116
|
+
request = null;
|
|
114
117
|
};
|
|
115
|
-
|
|
118
|
+
|
|
116
119
|
// Handle timeout
|
|
117
120
|
request.ontimeout = function handleTimeout() {
|
|
118
121
|
let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded';
|
package/lib/core/Axios.js
CHANGED
|
@@ -20,7 +20,7 @@ const validators = validator.validators;
|
|
|
20
20
|
*/
|
|
21
21
|
class Axios {
|
|
22
22
|
constructor(instanceConfig) {
|
|
23
|
-
this.defaults = instanceConfig;
|
|
23
|
+
this.defaults = instanceConfig || {};
|
|
24
24
|
this.interceptors = {
|
|
25
25
|
request: new InterceptorManager(),
|
|
26
26
|
response: new InterceptorManager()
|
|
@@ -97,6 +97,15 @@ class Axios {
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
// Set config.allowAbsoluteUrls
|
|
101
|
+
if (config.allowAbsoluteUrls !== undefined) {
|
|
102
|
+
// do nothing
|
|
103
|
+
} else if (this.defaults.allowAbsoluteUrls !== undefined) {
|
|
104
|
+
config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls;
|
|
105
|
+
} else {
|
|
106
|
+
config.allowAbsoluteUrls = true;
|
|
107
|
+
}
|
|
108
|
+
|
|
100
109
|
validator.assertOptions(config, {
|
|
101
110
|
baseUrl: validators.spelling('baseURL'),
|
|
102
111
|
withXsrfToken: validators.spelling('withXSRFToken')
|
|
@@ -144,8 +153,8 @@ class Axios {
|
|
|
144
153
|
|
|
145
154
|
if (!synchronousRequestInterceptors) {
|
|
146
155
|
const chain = [dispatchRequest.bind(this), undefined];
|
|
147
|
-
chain.unshift
|
|
148
|
-
chain.push
|
|
156
|
+
chain.unshift(...requestInterceptorChain);
|
|
157
|
+
chain.push(...responseInterceptorChain);
|
|
149
158
|
len = chain.length;
|
|
150
159
|
|
|
151
160
|
promise = Promise.resolve(config);
|
|
@@ -192,7 +201,7 @@ class Axios {
|
|
|
192
201
|
|
|
193
202
|
getUri(config) {
|
|
194
203
|
config = mergeConfig(this.defaults, config);
|
|
195
|
-
const fullPath = buildFullPath(config.baseURL, config.url);
|
|
204
|
+
const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
|
|
196
205
|
return buildURL(fullPath, config.params, config.paramsSerializer);
|
|
197
206
|
}
|
|
198
207
|
}
|
package/lib/core/AxiosError.js
CHANGED
|
@@ -89,11 +89,18 @@ AxiosError.from = (error, code, config, request, response, customProps) => {
|
|
|
89
89
|
return prop !== 'isAxiosError';
|
|
90
90
|
});
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
const msg = error && error.message ? error.message : 'Error';
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
// Prefer explicit code; otherwise copy the low-level error's code (e.g. ECONNREFUSED)
|
|
95
|
+
const errCode = code == null && error ? error.code : code;
|
|
96
|
+
AxiosError.call(axiosError, msg, errCode, config, request, response);
|
|
95
97
|
|
|
96
|
-
|
|
98
|
+
// Chain the original error on the standard field; non-enumerable to avoid JSON noise
|
|
99
|
+
if (error && axiosError.cause == null) {
|
|
100
|
+
Object.defineProperty(axiosError, 'cause', { value: error, configurable: true });
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
axiosError.name = (error && error.name) || 'Error';
|
|
97
104
|
|
|
98
105
|
customProps && Object.assign(axiosError, customProps);
|
|
99
106
|
|
package/lib/core/AxiosHeaders.js
CHANGED
|
@@ -100,10 +100,18 @@ class AxiosHeaders {
|
|
|
100
100
|
setHeaders(header, valueOrRewrite)
|
|
101
101
|
} else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {
|
|
102
102
|
setHeaders(parseHeaders(header), valueOrRewrite);
|
|
103
|
-
} else if (utils.
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
} else if (utils.isObject(header) && utils.isIterable(header)) {
|
|
104
|
+
let obj = {}, dest, key;
|
|
105
|
+
for (const entry of header) {
|
|
106
|
+
if (!utils.isArray(entry)) {
|
|
107
|
+
throw TypeError('Object iterator must return a key-value pair');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
obj[key = entry[0]] = (dest = obj[key]) ?
|
|
111
|
+
(utils.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]]) : entry[1];
|
|
106
112
|
}
|
|
113
|
+
|
|
114
|
+
setHeaders(obj, valueOrRewrite)
|
|
107
115
|
} else {
|
|
108
116
|
header != null && setHeader(valueOrRewrite, header, rewrite);
|
|
109
117
|
}
|
|
@@ -245,6 +253,10 @@ class AxiosHeaders {
|
|
|
245
253
|
return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\n');
|
|
246
254
|
}
|
|
247
255
|
|
|
256
|
+
getSetCookie() {
|
|
257
|
+
return this.get("set-cookie") || [];
|
|
258
|
+
}
|
|
259
|
+
|
|
248
260
|
get [Symbol.toStringTag]() {
|
|
249
261
|
return 'AxiosHeaders';
|
|
250
262
|
}
|
|
@@ -13,8 +13,9 @@ import combineURLs from '../helpers/combineURLs.js';
|
|
|
13
13
|
*
|
|
14
14
|
* @returns {string} The combined full path
|
|
15
15
|
*/
|
|
16
|
-
export default function buildFullPath(baseURL, requestedURL) {
|
|
17
|
-
|
|
16
|
+
export default function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {
|
|
17
|
+
let isRelativeUrl = !isAbsoluteURL(requestedURL);
|
|
18
|
+
if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) {
|
|
18
19
|
return combineURLs(baseURL, requestedURL);
|
|
19
20
|
}
|
|
20
21
|
return requestedURL;
|
|
@@ -46,7 +46,7 @@ export default function dispatchRequest(config) {
|
|
|
46
46
|
config.headers.setContentType('application/x-www-form-urlencoded', false);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
const adapter = adapters.getAdapter(config.adapter || defaults.adapter);
|
|
49
|
+
const adapter = adapters.getAdapter(config.adapter || defaults.adapter, config);
|
|
50
50
|
|
|
51
51
|
return adapter(config).then(function onAdapterResolution(response) {
|
|
52
52
|
throwIfCancellationRequested(config);
|
package/lib/core/mergeConfig.js
CHANGED
|
@@ -96,7 +96,7 @@ export default function mergeConfig(config1, config2) {
|
|
|
96
96
|
headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true)
|
|
97
97
|
};
|
|
98
98
|
|
|
99
|
-
utils.forEach(Object.keys(
|
|
99
|
+
utils.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) {
|
|
100
100
|
const merge = mergeMap[prop] || mergeDeepProperties;
|
|
101
101
|
const configValue = merge(config1[prop], config2[prop], prop);
|
|
102
102
|
(utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);
|
package/lib/defaults/index.js
CHANGED
|
@@ -111,7 +111,7 @@ const defaults = {
|
|
|
111
111
|
const strictJSONParsing = !silentJSONParsing && JSONRequested;
|
|
112
112
|
|
|
113
113
|
try {
|
|
114
|
-
return JSON.parse(data);
|
|
114
|
+
return JSON.parse(data, this.parseReviver);
|
|
115
115
|
} catch (e) {
|
|
116
116
|
if (strictJSONParsing) {
|
|
117
117
|
if (e.name === 'SyntaxError') {
|