优化首页的下拉刷新、数据排序、绑定后刷新
This commit is contained in:
290
node_modules/axios/lib/adapters/http.js
generated
vendored
290
node_modules/axios/lib/adapters/http.js
generated
vendored
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
import utils from './../utils.js';
|
||||
import settle from './../core/settle.js';
|
||||
import buildFullPath from '../core/buildFullPath.js';
|
||||
@ -7,6 +5,7 @@ import buildURL from './../helpers/buildURL.js';
|
||||
import proxyFromEnv from 'proxy-from-env';
|
||||
import http from 'http';
|
||||
import https from 'https';
|
||||
import http2 from 'http2';
|
||||
import util from 'util';
|
||||
import followRedirects from 'follow-redirects';
|
||||
import zlib from 'zlib';
|
||||
@ -25,6 +24,7 @@ import readBlob from "../helpers/readBlob.js";
|
||||
import ZlibHeaderTransformStream from '../helpers/ZlibHeaderTransformStream.js';
|
||||
import callbackify from "../helpers/callbackify.js";
|
||||
import {progressEventReducer, progressEventDecorator, asyncDecorator} from "../helpers/progressEventReducer.js";
|
||||
import estimateDataURLDecodedBytes from '../helpers/estimateDataURLDecodedBytes.js';
|
||||
|
||||
const zlibOptions = {
|
||||
flush: zlib.constants.Z_SYNC_FLUSH,
|
||||
@ -46,6 +46,7 @@ const supportedProtocols = platform.protocols.map(protocol => {
|
||||
return protocol + ':';
|
||||
});
|
||||
|
||||
|
||||
const flushOnFinish = (stream, [throttled, flush]) => {
|
||||
stream
|
||||
.on('end', flush)
|
||||
@ -54,6 +55,102 @@ const flushOnFinish = (stream, [throttled, flush]) => {
|
||||
return throttled;
|
||||
}
|
||||
|
||||
class Http2Sessions {
|
||||
constructor() {
|
||||
this.sessions = Object.create(null);
|
||||
}
|
||||
|
||||
getSession(authority, options) {
|
||||
options = Object.assign({
|
||||
sessionTimeout: 1000
|
||||
}, options);
|
||||
|
||||
let authoritySessions = this.sessions[authority];
|
||||
|
||||
if (authoritySessions) {
|
||||
let len = authoritySessions.length;
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
const [sessionHandle, sessionOptions] = authoritySessions[i];
|
||||
if (!sessionHandle.destroyed && !sessionHandle.closed && util.isDeepStrictEqual(sessionOptions, options)) {
|
||||
return sessionHandle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const session = http2.connect(authority, options);
|
||||
|
||||
let removed;
|
||||
|
||||
const removeSession = () => {
|
||||
if (removed) {
|
||||
return;
|
||||
}
|
||||
|
||||
removed = true;
|
||||
|
||||
let entries = authoritySessions, len = entries.length, i = len;
|
||||
|
||||
while (i--) {
|
||||
if (entries[i][0] === session) {
|
||||
if (len === 1) {
|
||||
delete this.sessions[authority];
|
||||
} else {
|
||||
entries.splice(i, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const originalRequestFn = session.request;
|
||||
|
||||
const {sessionTimeout} = options;
|
||||
|
||||
if(sessionTimeout != null) {
|
||||
|
||||
let timer;
|
||||
let streamsCount = 0;
|
||||
|
||||
session.request = function () {
|
||||
const stream = originalRequestFn.apply(this, arguments);
|
||||
|
||||
streamsCount++;
|
||||
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
}
|
||||
|
||||
stream.once('close', () => {
|
||||
if (!--streamsCount) {
|
||||
timer = setTimeout(() => {
|
||||
timer = null;
|
||||
removeSession();
|
||||
}, sessionTimeout);
|
||||
}
|
||||
});
|
||||
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
|
||||
session.once('close', removeSession);
|
||||
|
||||
let entry = [
|
||||
session,
|
||||
options
|
||||
];
|
||||
|
||||
authoritySessions ? authoritySessions.push(entry) : authoritySessions = this.sessions[authority] = [entry];
|
||||
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
||||
const http2Sessions = new Http2Sessions();
|
||||
|
||||
|
||||
/**
|
||||
* If the proxy or config beforeRedirects functions are defined, call them with the options
|
||||
* object.
|
||||
@ -165,16 +262,75 @@ const resolveFamily = ({address, family}) => {
|
||||
|
||||
const buildAddressEntry = (address, family) => resolveFamily(utils.isObject(address) ? address : {address, family});
|
||||
|
||||
const http2Transport = {
|
||||
request(options, cb) {
|
||||
const authority = options.protocol + '//' + options.hostname + ':' + (options.port || 80);
|
||||
|
||||
const {http2Options, headers} = options;
|
||||
|
||||
const session = http2Sessions.getSession(authority, http2Options);
|
||||
|
||||
const {
|
||||
HTTP2_HEADER_SCHEME,
|
||||
HTTP2_HEADER_METHOD,
|
||||
HTTP2_HEADER_PATH,
|
||||
HTTP2_HEADER_STATUS
|
||||
} = http2.constants;
|
||||
|
||||
const http2Headers = {
|
||||
[HTTP2_HEADER_SCHEME]: options.protocol.replace(':', ''),
|
||||
[HTTP2_HEADER_METHOD]: options.method,
|
||||
[HTTP2_HEADER_PATH]: options.path,
|
||||
}
|
||||
|
||||
utils.forEach(headers, (header, name) => {
|
||||
name.charAt(0) !== ':' && (http2Headers[name] = header);
|
||||
});
|
||||
|
||||
const req = session.request(http2Headers);
|
||||
|
||||
req.once('response', (responseHeaders) => {
|
||||
const response = req; //duplex
|
||||
|
||||
responseHeaders = Object.assign({}, responseHeaders);
|
||||
|
||||
const status = responseHeaders[HTTP2_HEADER_STATUS];
|
||||
|
||||
delete responseHeaders[HTTP2_HEADER_STATUS];
|
||||
|
||||
response.headers = responseHeaders;
|
||||
|
||||
response.statusCode = +status;
|
||||
|
||||
cb(response);
|
||||
})
|
||||
|
||||
return req;
|
||||
}
|
||||
}
|
||||
|
||||
/*eslint consistent-return:0*/
|
||||
export default isHttpAdapterSupported && function httpAdapter(config) {
|
||||
return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {
|
||||
let {data, lookup, family} = config;
|
||||
let {data, lookup, family, httpVersion = 1, http2Options} = config;
|
||||
const {responseType, responseEncoding} = config;
|
||||
const method = config.method.toUpperCase();
|
||||
let isDone;
|
||||
let rejected = false;
|
||||
let req;
|
||||
|
||||
httpVersion = +httpVersion;
|
||||
|
||||
if (Number.isNaN(httpVersion)) {
|
||||
throw TypeError(`Invalid protocol version: '${config.httpVersion}' is not a number`);
|
||||
}
|
||||
|
||||
if (httpVersion !== 1 && httpVersion !== 2) {
|
||||
throw TypeError(`Unsupported protocol version '${httpVersion}'`);
|
||||
}
|
||||
|
||||
const isHttp2 = httpVersion === 2;
|
||||
|
||||
if (lookup) {
|
||||
const _lookup = callbackify(lookup, (value) => utils.isArray(value) ? value : [value]);
|
||||
// hotfix to support opt.all option which is required for node 20.x
|
||||
@ -191,8 +347,17 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
|
||||
}
|
||||
}
|
||||
|
||||
// temporary internal emitter until the AxiosRequest class will be implemented
|
||||
const emitter = new EventEmitter();
|
||||
const abortEmitter = new EventEmitter();
|
||||
|
||||
function abort(reason) {
|
||||
try {
|
||||
abortEmitter.emit('abort', !reason || reason.type ? new CanceledError(null, config, req) : reason);
|
||||
} catch(err) {
|
||||
console.warn('emit error', err);
|
||||
}
|
||||
}
|
||||
|
||||
abortEmitter.once('abort', reject);
|
||||
|
||||
const onFinished = () => {
|
||||
if (config.cancelToken) {
|
||||
@ -203,23 +368,9 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
|
||||
config.signal.removeEventListener('abort', abort);
|
||||
}
|
||||
|
||||
emitter.removeAllListeners();
|
||||
abortEmitter.removeAllListeners();
|
||||
}
|
||||
|
||||
onDone((value, isRejected) => {
|
||||
isDone = true;
|
||||
if (isRejected) {
|
||||
rejected = true;
|
||||
onFinished();
|
||||
}
|
||||
});
|
||||
|
||||
function abort(reason) {
|
||||
emitter.emit('abort', !reason || reason.type ? new CanceledError(null, config, req) : reason);
|
||||
}
|
||||
|
||||
emitter.once('abort', reject);
|
||||
|
||||
if (config.cancelToken || config.signal) {
|
||||
config.cancelToken && config.cancelToken.subscribe(abort);
|
||||
if (config.signal) {
|
||||
@ -227,12 +378,52 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
|
||||
}
|
||||
}
|
||||
|
||||
onDone((response, isRejected) => {
|
||||
isDone = true;
|
||||
|
||||
if (isRejected) {
|
||||
rejected = true;
|
||||
onFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
const {data} = response;
|
||||
|
||||
if (data instanceof stream.Readable || data instanceof stream.Duplex) {
|
||||
const offListeners = stream.finished(data, () => {
|
||||
offListeners();
|
||||
onFinished();
|
||||
});
|
||||
} else {
|
||||
onFinished();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Parse url
|
||||
const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);
|
||||
const parsed = new URL(fullPath, platform.hasBrowserEnv ? platform.origin : undefined);
|
||||
const protocol = parsed.protocol || supportedProtocols[0];
|
||||
|
||||
if (protocol === 'data:') {
|
||||
// Apply the same semantics as HTTP: only enforce if a finite, non-negative cap is set.
|
||||
if (config.maxContentLength > -1) {
|
||||
// Use the exact string passed to fromDataURI (config.url); fall back to fullPath if needed.
|
||||
const dataUrl = String(config.url || fullPath || '');
|
||||
const estimated = estimateDataURLDecodedBytes(dataUrl);
|
||||
|
||||
if (estimated > config.maxContentLength) {
|
||||
return reject(new AxiosError(
|
||||
'maxContentLength size of ' + config.maxContentLength + ' exceeded',
|
||||
AxiosError.ERR_BAD_RESPONSE,
|
||||
config
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let convertedData;
|
||||
|
||||
if (method !== 'GET') {
|
||||
@ -418,7 +609,8 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
|
||||
protocol,
|
||||
family,
|
||||
beforeRedirect: dispatchBeforeRedirect,
|
||||
beforeRedirects: {}
|
||||
beforeRedirects: {},
|
||||
http2Options
|
||||
};
|
||||
|
||||
// cacheable-lookup integration hotfix
|
||||
@ -435,18 +627,23 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
|
||||
let transport;
|
||||
const isHttpsRequest = isHttps.test(options.protocol);
|
||||
options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;
|
||||
if (config.transport) {
|
||||
transport = config.transport;
|
||||
} else if (config.maxRedirects === 0) {
|
||||
transport = isHttpsRequest ? https : http;
|
||||
|
||||
if (isHttp2) {
|
||||
transport = http2Transport;
|
||||
} else {
|
||||
if (config.maxRedirects) {
|
||||
options.maxRedirects = config.maxRedirects;
|
||||
if (config.transport) {
|
||||
transport = config.transport;
|
||||
} else if (config.maxRedirects === 0) {
|
||||
transport = isHttpsRequest ? https : http;
|
||||
} else {
|
||||
if (config.maxRedirects) {
|
||||
options.maxRedirects = config.maxRedirects;
|
||||
}
|
||||
if (config.beforeRedirect) {
|
||||
options.beforeRedirects.config = config.beforeRedirect;
|
||||
}
|
||||
transport = isHttpsRequest ? httpsFollow : httpFollow;
|
||||
}
|
||||
if (config.beforeRedirect) {
|
||||
options.beforeRedirects.config = config.beforeRedirect;
|
||||
}
|
||||
transport = isHttpsRequest ? httpsFollow : httpFollow;
|
||||
}
|
||||
|
||||
if (config.maxBodyLength > -1) {
|
||||
@ -466,7 +663,7 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
|
||||
|
||||
const streams = [res];
|
||||
|
||||
const responseLength = +res.headers['content-length'];
|
||||
const responseLength = utils.toFiniteNumber(res.headers['content-length']);
|
||||
|
||||
if (onDownloadProgress || maxDownloadRate) {
|
||||
const transformStream = new AxiosTransformStream({
|
||||
@ -529,10 +726,7 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
|
||||
|
||||
responseStream = streams.length > 1 ? stream.pipeline(streams, utils.noop) : streams[0];
|
||||
|
||||
const offListeners = stream.finished(responseStream, () => {
|
||||
offListeners();
|
||||
onFinished();
|
||||
});
|
||||
|
||||
|
||||
const response = {
|
||||
status: res.statusCode,
|
||||
@ -558,7 +752,7 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
|
||||
// stream.destroy() emit aborted event before calling reject() on Node.js v16
|
||||
rejected = true;
|
||||
responseStream.destroy();
|
||||
reject(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded',
|
||||
abort(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded',
|
||||
AxiosError.ERR_BAD_RESPONSE, config, lastRequest));
|
||||
}
|
||||
});
|
||||
@ -600,7 +794,7 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
|
||||
});
|
||||
}
|
||||
|
||||
emitter.once('abort', err => {
|
||||
abortEmitter.once('abort', err => {
|
||||
if (!responseStream.destroyed) {
|
||||
responseStream.emit('error', err);
|
||||
responseStream.destroy();
|
||||
@ -608,9 +802,12 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
|
||||
});
|
||||
});
|
||||
|
||||
emitter.once('abort', err => {
|
||||
reject(err);
|
||||
req.destroy(err);
|
||||
abortEmitter.once('abort', err => {
|
||||
if (req.close) {
|
||||
req.close();
|
||||
} else {
|
||||
req.destroy(err);
|
||||
}
|
||||
});
|
||||
|
||||
// Handle errors
|
||||
@ -632,7 +829,7 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
|
||||
const timeout = parseInt(config.timeout, 10);
|
||||
|
||||
if (Number.isNaN(timeout)) {
|
||||
reject(new AxiosError(
|
||||
abort(new AxiosError(
|
||||
'error trying to parse `config.timeout` to int',
|
||||
AxiosError.ERR_BAD_OPTION_VALUE,
|
||||
config,
|
||||
@ -654,14 +851,16 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
|
||||
if (config.timeoutErrorMessage) {
|
||||
timeoutErrorMessage = config.timeoutErrorMessage;
|
||||
}
|
||||
reject(new AxiosError(
|
||||
abort(new AxiosError(
|
||||
timeoutErrorMessage,
|
||||
transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,
|
||||
config,
|
||||
req
|
||||
));
|
||||
abort();
|
||||
});
|
||||
} else {
|
||||
// explicitly reset the socket timeout value for a possible `keep-alive` request
|
||||
req.setTimeout(0);
|
||||
}
|
||||
|
||||
|
||||
@ -687,7 +886,8 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
|
||||
|
||||
data.pipe(req);
|
||||
} else {
|
||||
req.end(data);
|
||||
data && req.write(data);
|
||||
req.end();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user