wodax-umi-request
Version:
A request tool based on fetch. Cloned from umi-request
1,159 lines (956 loc) • 33.4 kB
JavaScript
import { parse, stringify } from 'query-string';
import 'isomorphic-fetch';
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
var defineProperty = _defineProperty;
function _objectSpread(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === 'function') {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
ownKeys.forEach(function (key) {
defineProperty(target, key, source[key]);
});
}
return target;
}
var objectSpread = _objectSpread;
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var classCallCheck = _classCallCheck;
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
var createClass = _createClass;
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var _typeof_1 = createCommonjsModule(function (module) {
function _typeof2(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof2 = function _typeof2(obj) { return typeof obj; }; } else { _typeof2 = function _typeof2(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof2(obj); }
function _typeof(obj) {
if (typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol") {
module.exports = _typeof = function _typeof(obj) {
return _typeof2(obj);
};
} else {
module.exports = _typeof = function _typeof(obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof2(obj);
};
}
return _typeof(obj);
}
module.exports = _typeof;
});
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
arr2[i] = arr[i];
}
return arr2;
}
}
var arrayWithoutHoles = _arrayWithoutHoles;
function _iterableToArray(iter) {
if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
}
var iterableToArray = _iterableToArray;
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance");
}
var nonIterableSpread = _nonIterableSpread;
function _toConsumableArray(arr) {
return arrayWithoutHoles(arr) || iterableToArray(arr) || nonIterableSpread();
}
var toConsumableArray = _toConsumableArray;
// 返回一个组合了所有插件的“插件”
function compose(middlewares) {
if (!Array.isArray(middlewares)) throw new TypeError('Middlewares must be an array!');
var middlewaresLen = middlewares.length;
for (var i = 0; i < middlewaresLen; i++) {
if (typeof middlewares[i] !== 'function') {
throw new TypeError('Middleware must be componsed of function');
}
}
return function wrapMiddlewares(params, next) {
var index = -1;
function dispatch(i) {
if (i <= index) {
return Promise.reject(new Error('next() should not be called multiple times in one middleware!'));
}
index = i;
var fn = middlewares[i] || next;
if (!fn) return Promise.resolve();
try {
return Promise.resolve(fn(params, function () {
return dispatch(i + 1);
}));
} catch (err) {
return Promise.reject(err);
}
}
return dispatch(0);
};
}
var Onion =
/*#__PURE__*/
function () {
function Onion(defaultMiddlewares) {
classCallCheck(this, Onion);
if (!Array.isArray(defaultMiddlewares)) throw new TypeError('Default middlewares must be an array!');
this.middlewares = toConsumableArray(defaultMiddlewares);
}
createClass(Onion, [{
key: "use",
// 内置内核中间件长度
value: function use(newMiddleware) {
var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
global: false,
core: false
};
var core = false;
var global = false;
if (typeof opts === 'number') {
if (process && process.env && process.env.NODE_ENV === 'development') {
console.warn('use() options should be object, number property would be deprecated in future,please update use() options to "{ core: true }".');
}
core = true;
global = false;
} else if (_typeof_1(opts) === 'object' && opts) {
global = opts.global || false;
core = opts.core || false;
} // 全局中间件
if (global) {
Onion.globalMiddlewares.splice(Onion.globalMiddlewares.length - Onion.defaultGlobalMiddlewaresLength, 0, newMiddleware);
return;
} // 内核中间件
if (core) {
Onion.coreMiddlewares.splice(Onion.coreMiddlewares.length - Onion.defaultCoreMiddlewaresLength, 0, newMiddleware);
return;
} // 实例中间件
this.middlewares.push(newMiddleware);
}
}, {
key: "execute",
value: function execute() {
var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var fn = compose([].concat(toConsumableArray(this.middlewares), toConsumableArray(Onion.globalMiddlewares), toConsumableArray(Onion.coreMiddlewares)));
return fn(params);
}
}]);
return Onion;
}();
Onion.globalMiddlewares = [];
Onion.defaultGlobalMiddlewaresLength = 0;
Onion.coreMiddlewares = [];
Onion.defaultCoreMiddlewaresLength = 0;
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
var assertThisInitialized = _assertThisInitialized;
function _possibleConstructorReturn(self, call) {
if (call && (_typeof_1(call) === "object" || typeof call === "function")) {
return call;
}
return assertThisInitialized(self);
}
var possibleConstructorReturn = _possibleConstructorReturn;
var getPrototypeOf = createCommonjsModule(function (module) {
function _getPrototypeOf(o) {
module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
module.exports = _getPrototypeOf;
});
var setPrototypeOf = createCommonjsModule(function (module) {
function _setPrototypeOf(o, p) {
module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
module.exports = _setPrototypeOf;
});
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
if (superClass) setPrototypeOf(subClass, superClass);
}
var inherits = _inherits;
function _isNativeFunction(fn) {
return Function.toString.call(fn).indexOf("[native code]") !== -1;
}
var isNativeFunction = _isNativeFunction;
var construct = createCommonjsModule(function (module) {
function isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _construct(Parent, args, Class) {
if (isNativeReflectConstruct()) {
module.exports = _construct = Reflect.construct;
} else {
module.exports = _construct = function _construct(Parent, args, Class) {
var a = [null];
a.push.apply(a, args);
var Constructor = Function.bind.apply(Parent, a);
var instance = new Constructor();
if (Class) setPrototypeOf(instance, Class.prototype);
return instance;
};
}
return _construct.apply(null, arguments);
}
module.exports = _construct;
});
var wrapNativeSuper = createCommonjsModule(function (module) {
function _wrapNativeSuper(Class) {
var _cache = typeof Map === "function" ? new Map() : undefined;
module.exports = _wrapNativeSuper = function _wrapNativeSuper(Class) {
if (Class === null || !isNativeFunction(Class)) return Class;
if (typeof Class !== "function") {
throw new TypeError("Super expression must either be null or a function");
}
if (typeof _cache !== "undefined") {
if (_cache.has(Class)) return _cache.get(Class);
_cache.set(Class, Wrapper);
}
function Wrapper() {
return construct(Class, arguments, getPrototypeOf(this).constructor);
}
Wrapper.prototype = Object.create(Class.prototype, {
constructor: {
value: Wrapper,
enumerable: false,
writable: true,
configurable: true
}
});
return setPrototypeOf(Wrapper, Class);
};
return _wrapNativeSuper(Class);
}
module.exports = _wrapNativeSuper;
});
var MapCache =
/*#__PURE__*/
function () {
function MapCache(options) {
classCallCheck(this, MapCache);
this.cache = new Map();
this.timer = {};
this.maxCache = options.maxCache || 0;
}
createClass(MapCache, [{
key: "get",
value: function get(key) {
return this.cache.get(JSON.stringify(key));
}
}, {
key: "set",
value: function set(key, value) {
var _this = this;
var ttl = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 60000;
// 如果超过最大缓存数, 删除头部的第一个缓存.
if (this.maxCache > 0 && this.cache.size >= this.maxCache) {
var deleteKey = toConsumableArray(this.cache.keys())[0];
this.cache.delete(deleteKey);
if (this.timer[deleteKey]) {
clearTimeout(this.timer[deleteKey]);
}
}
var cacheKey = JSON.stringify(key);
this.cache.set(cacheKey, value);
if (ttl > 0) {
this.timer[cacheKey] = setTimeout(function () {
_this.cache.delete(cacheKey);
delete _this.timer[cacheKey];
}, ttl);
}
}
}, {
key: "delete",
value: function _delete(key) {
var cacheKey = JSON.stringify(key);
delete this.timer[cacheKey];
return this.cache.delete(cacheKey);
}
}, {
key: "clear",
value: function clear() {
this.timer = {};
return this.cache.clear();
}
}]);
return MapCache;
}();
/**
* 请求异常
*/
var RequestError =
/*#__PURE__*/
function (_Error) {
inherits(RequestError, _Error);
function RequestError(text, request) {
var _this2;
classCallCheck(this, RequestError);
_this2 = possibleConstructorReturn(this, getPrototypeOf(RequestError).call(this, text));
_this2.name = 'RequestError';
_this2.request = request;
return _this2;
}
return RequestError;
}(wrapNativeSuper(Error));
/**
* 响应异常
*/
var ResponseError =
/*#__PURE__*/
function (_Error2) {
inherits(ResponseError, _Error2);
function ResponseError(response, text, data, request) {
var _this3;
classCallCheck(this, ResponseError);
_this3 = possibleConstructorReturn(this, getPrototypeOf(ResponseError).call(this, text || response.statusText));
_this3.name = 'ResponseError';
_this3.data = data;
_this3.response = response;
_this3.request = request;
return _this3;
}
return ResponseError;
}(wrapNativeSuper(Error));
/**
* http://gitlab.alipay-inc.com/KBSJ/gxt/blob/release_gxt_S8928905_20180531/src/util/request.js#L63
* 支持gbk
*/
function readerGBK(file) {
return new Promise(function (resolve, reject) {
var reader = new FileReader();
reader.onload = function () {
resolve(reader.result);
};
reader.onerror = reject;
reader.readAsText(file, 'GBK'); // setup GBK decoding
});
}
/**
* 安全的JSON.parse
*/
function safeJsonParse(data) {
var throwErrIfParseFail = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var response = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var request = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
try {
return JSON.parse(data);
} catch (e) {
if (throwErrIfParseFail) {
throw new ResponseError(response, 'JSON.parse fail', data, request);
}
} // eslint-disable-line no-empty
return data;
}
function timeout2Throw(msec, request) {
return new Promise(function (_, reject) {
setTimeout(function () {
reject(new RequestError("timeout of ".concat(msec, "ms exceeded"), request));
}, msec);
});
} // If request options contain 'cancelToken', reject request when token has been canceled
function cancel2Throw(opt) {
return new Promise(function (_, reject) {
if (opt.cancelToken) {
opt.cancelToken.promise.then(function (cancel) {
reject(cancel);
});
}
});
}
var toString = Object.prototype.toString; // Check env is browser or node
function getEnv() {
var env; // Only Node.JS has a process variable that is of [[Class]] process
if (typeof process !== 'undefined' && toString.call(process) === '[object process]') {
// For node use HTTP adapter
env = 'NODE';
}
if (typeof XMLHttpRequest !== 'undefined') {
env = 'BROWSER';
}
return env;
}
function isArray(val) {
return _typeof_1(val) === 'object' && Object.prototype.toString.call(val) === '[object Array]';
}
function isURLSearchParams(val) {
return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;
}
function isDate(val) {
return _typeof_1(val) === 'object' && Object.prototype.toString.call(val) === '[object Date]';
}
function isObject(val) {
return val !== null && _typeof_1(val) === 'object';
}
function forEach2ObjArr(target, callback) {
if (!target) return;
if (_typeof_1(target) !== 'object') {
target = [target];
}
if (isArray(target)) {
for (var i = 0; i < target.length; i++) {
callback.call(null, target[i], i, target);
}
} else {
for (var key in target) {
if (Object.prototype.hasOwnProperty.call(target, key)) {
callback.call(null, target[key], key, target);
}
}
}
}
function getParamObject(val) {
if (isURLSearchParams(val)) {
return parse(val.toString());
}
if (typeof val === 'string') {
return [val];
}
return val;
}
// 前后缀拦截
var addfix = function addfix(url) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var prefix = options.prefix,
suffix = options.suffix;
if (prefix) {
url = "".concat(prefix).concat(url);
}
if (suffix) {
url = "".concat(url).concat(suffix);
}
return {
url: url,
options: options
};
};
function fetchMiddleware(ctx, next) {
if (!ctx) return next();
var _ctx$req = ctx.req;
_ctx$req = _ctx$req === void 0 ? {} : _ctx$req;
var _ctx$req$options = _ctx$req.options,
options = _ctx$req$options === void 0 ? {} : _ctx$req$options,
_ctx$req$url = _ctx$req.url,
url = _ctx$req$url === void 0 ? '' : _ctx$req$url,
cache = ctx.cache,
responseInterceptors = ctx.responseInterceptors;
var _options$timeout = options.timeout,
timeout = _options$timeout === void 0 ? 0 : _options$timeout,
_options$__umiRequest = options.__umiRequestCoreType__,
__umiRequestCoreType__ = _options$__umiRequest === void 0 ? 'normal' : _options$__umiRequest,
_options$useCache = options.useCache,
useCache = _options$useCache === void 0 ? false : _options$useCache,
_options$method = options.method,
method = _options$method === void 0 ? 'get' : _options$method,
params = options.params,
ttl = options.ttl;
if (__umiRequestCoreType__ !== 'normal') {
if (process && process.env && process.env.NODE_ENV === 'development') {
console.warn('__umiRequestCoreType__ is a internal property that use in umi-request, change its value would affect the behavior of request! It only use when you want to extend the request core.');
}
return next();
}
var adapter = fetch;
if (!adapter) {
throw new Error('Global fetch not exist!');
} // 从缓存池检查是否有缓存数据
var isBrowser = getEnv() === 'BROWSER';
var needCache = method.toLowerCase() === 'get' && useCache && isBrowser;
if (needCache) {
var responseCache = cache.get({
url: url,
params: params
});
if (responseCache) {
responseCache = responseCache.clone();
responseCache.useCache = true;
ctx.res = responseCache;
return next();
}
}
var response; // 超时处理、取消请求处理
if (timeout > 0) {
response = Promise.race([cancel2Throw(options), adapter(url, options), timeout2Throw(timeout, ctx.req)]);
} else {
response = Promise.race([cancel2Throw(options), adapter(url, options)]);
} // 兼容老版本 response.interceptor
responseInterceptors.forEach(function (handler) {
/// Note:response 大部分特性是只读的,修改并没有意义,所以使用克隆方式 (sunzhifeng 2019.10.11)
if (!!options["MODIFY_RESPONSE_OBJECT_TRY"]) {
response = response.then(function (res) {
return handler(res, options);
});
} else {
response = response.then(function (res) {
handler(res.clone(), options);
return res;
});
}
});
return response.then(function (res) {
// 是否存入缓存池
if (needCache) {
if (res.status === 200) {
var copy = res.clone();
copy.useCache = true;
cache.set({
url: url,
params: params
}, copy, ttl);
}
}
ctx.res = res;
return next();
});
}
function parseResponseMiddleware(ctx, next) {
var copy;
return next().then(function () {
if (!ctx) return;
var _ctx$res = ctx.res,
res = _ctx$res === void 0 ? {} : _ctx$res,
_ctx$req = ctx.req,
req = _ctx$req === void 0 ? {} : _ctx$req;
var _ref = req || {},
_ref$options = _ref.options;
_ref$options = _ref$options === void 0 ? {} : _ref$options;
var _ref$options$response = _ref$options.responseType,
responseType = _ref$options$response === void 0 ? 'json' : _ref$options$response,
_ref$options$charset = _ref$options.charset,
charset = _ref$options$charset === void 0 ? 'utf8' : _ref$options$charset,
_ref$options$getRespo = _ref$options.getResponse,
_ref$options$throwErr = _ref$options.throwErrIfParseFail,
throwErrIfParseFail = _ref$options$throwErr === void 0 ? false : _ref$options$throwErr,
_ref$options$parseRes = _ref$options.parseResponse,
parseResponse = _ref$options$parseRes === void 0 ? true : _ref$options$parseRes;
if (!parseResponse) {
return;
}
if (!res || !res.clone) {
return;
} // 只在浏览器环境对 response 做克隆, node 环境如果对 response 克隆会有问题:https://github.com/bitinn/node-fetch/issues/553
copy = getEnv() === 'BROWSER' ? res.clone() : res;
copy.useCache = res.useCache || false; // 解析数据
if (charset === 'gbk') {
try {
return res.blob().then(readerGBK).then(function (d) {
return safeJsonParse(d, false, copy, req);
});
} catch (e) {
throw new ResponseError(copy, e.message, null, req);
}
} else if (responseType === 'json') {
return res.text().then(function (d) {
return safeJsonParse(d, throwErrIfParseFail, copy, req);
});
}
try {
// 其他如text, blob, arrayBuffer, formData
return res[responseType]();
} catch (e) {
throw new ResponseError(copy, 'responseType not support', null, req);
}
}).then(function (body) {
if (!ctx) return;
var _ctx$res2 = ctx.res,
_ctx$req2 = ctx.req,
req = _ctx$req2 === void 0 ? {} : _ctx$req2;
var _ref2 = req || {},
_ref2$options = _ref2.options;
_ref2$options = _ref2$options === void 0 ? {} : _ref2$options;
var _ref2$options$getResp = _ref2$options.getResponse,
getResponse = _ref2$options$getResp === void 0 ? false : _ref2$options$getResp;
if (!copy) {
return;
}
if (copy.status >= 200 && copy.status < 300) {
// 提供源response, 以便自定义处理
if (getResponse) {
ctx.res = {
data: body,
response: copy
};
return;
}
ctx.res = body;
return;
}
throw new ResponseError(copy, 'http error', body, req);
});
}
function simplePostMiddleware(ctx, next) {
if (!ctx) return next();
var _ctx$req = ctx.req;
_ctx$req = _ctx$req === void 0 ? {} : _ctx$req;
var _ctx$req$options = _ctx$req.options,
options = _ctx$req$options === void 0 ? {} : _ctx$req$options;
var _options$method = options.method,
method = _options$method === void 0 ? 'get' : _options$method;
if (['post', 'put', 'patch', 'delete'].indexOf(method.toLowerCase()) === -1) {
return next();
}
var _options$requestType = options.requestType,
requestType = _options$requestType === void 0 ? 'json' : _options$requestType,
data = options.data; // 数据使用类axios的新字段data, 避免引用后影响旧代码, 如将body stringify多次
if (data) {
var dataType = Object.prototype.toString.call(data);
if (dataType === '[object Object]' || dataType === '[object Array]') {
if (requestType === 'json') {
options.headers = objectSpread({
Accept: 'application/json',
'Content-Type': 'application/json;charset=UTF-8'
}, options.headers);
options.body = JSON.stringify(data);
} else if (requestType === 'form') {
options.headers = objectSpread({
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
}, options.headers);
options.body = stringify(data);
}
} else {
// 其他 requestType 自定义header
options.headers = objectSpread({
Accept: 'application/json'
}, options.headers);
options.body = data;
}
}
ctx.req.options = options;
return next();
}
function paramsSerialize(params, paramsSerializer) {
var serializedParams;
var jsonStringifiedParams; // 支持参数自动拼装,其他 method 也可用,不冲突
if (params) {
if (paramsSerializer) {
serializedParams = paramsSerializer(params);
} else if (isURLSearchParams(params)) {
serializedParams = params.toString();
} else {
if (isArray(params)) {
jsonStringifiedParams = [];
forEach2ObjArr(params, function (item) {
if (item === null || typeof item === 'undefined') {
jsonStringifiedParams.push(item);
} else {
jsonStringifiedParams.push(isObject(item) ? JSON.stringify(item) : item);
}
});
serializedParams = stringify(jsonStringifiedParams);
} else {
jsonStringifiedParams = {};
forEach2ObjArr(params, function (value, key) {
var jsonStringifiedValue = value;
if (value === null || typeof value === 'undefined') {
jsonStringifiedParams[key] = value;
} else if (isDate(value)) {
jsonStringifiedValue = value.toISOString();
} else if (isArray(value)) {
jsonStringifiedValue = value;
} else if (isObject(value)) {
jsonStringifiedValue = JSON.stringify(value);
}
jsonStringifiedParams[key] = jsonStringifiedValue;
});
var tmp = stringify(jsonStringifiedParams);
serializedParams = tmp;
}
}
}
return serializedParams;
} // 对请求参数做处理,实现 query 简化、 post 简化
function simpleGetMiddleware(ctx, next) {
if (!ctx) return next();
var _ctx$req = ctx.req;
_ctx$req = _ctx$req === void 0 ? {} : _ctx$req;
var _ctx$req$options = _ctx$req.options,
options = _ctx$req$options === void 0 ? {} : _ctx$req$options;
var paramsSerializer = options.paramsSerializer,
params = options.params;
var _ctx$req2 = ctx.req;
_ctx$req2 = _ctx$req2 === void 0 ? {} : _ctx$req2;
var _ctx$req2$url = _ctx$req2.url,
url = _ctx$req2$url === void 0 ? '' : _ctx$req2$url; // 将 method 改为大写
options.method = options.method ? options.method.toUpperCase() : 'GET'; // 设置 credentials 默认值为 same-origin,确保当开发者没有设置时,各浏览器对请求是否发送 cookies 保持一致的行为
// - omit: 从不发送cookies.
// - same-origin: 只有当URL与响应脚本同源才发送 cookies、 HTTP Basic authentication 等验证信息.(浏览器默认值,在旧版本浏览器,例如safari 11依旧是omit,safari 12已更改)
// - include: 不论是不是跨域的请求,总是发送请求资源域在本地的 cookies、 HTTP Basic authentication 等验证信息.
options.credentials = options.credentials || 'same-origin'; // 支持类似axios 参数自动拼装, 其他method也可用, 不冲突.
var serializedParams = paramsSerialize(params, paramsSerializer);
ctx.req.originUrl = url;
if (serializedParams) {
var urlSign = url.indexOf('?') !== -1 ? '&' : '?';
ctx.req.url = "".concat(url).concat(urlSign).concat(serializedParams);
}
ctx.req.options = options;
return next();
}
var requestInterceptors = [addfix];
var responseInterceptors = []; // 初始化全局和内核中间件
var globalMiddlewares = [simplePostMiddleware, simpleGetMiddleware, parseResponseMiddleware];
var coreMiddlewares = [fetchMiddleware];
Onion.globalMiddlewares = globalMiddlewares;
Onion.defaultGlobalMiddlewaresLength = globalMiddlewares.length;
Onion.coreMiddlewares = coreMiddlewares;
Onion.defaultCoreMiddlewaresLength = coreMiddlewares.length;
var Core =
/*#__PURE__*/
function () {
function Core(initOptions) {
classCallCheck(this, Core);
this.onion = new Onion([]);
this.fetchIndex = 0; // 【即将废弃】请求中间件位置
this.mapCache = new MapCache(initOptions);
}
createClass(Core, [{
key: "use",
value: function use(newMiddleware) {
var opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
global: false,
core: false
};
this.onion.use(newMiddleware, opt);
return this;
}
}, {
key: "request",
value: function request(url, options) {
var onion = this.onion;
var obj = {
req: {
url: url,
options: options
},
res: null,
cache: this.mapCache,
responseInterceptors: responseInterceptors
};
if (typeof url !== 'string') {
throw new Error('url MUST be a string');
}
return new Promise(function (resolve, reject) {
Core.dealRequestInterceptors(obj).then(function () {
return onion.execute(obj);
}).then(function () {
resolve(obj.res);
}).catch(function (error) {
var errorHandler = obj.req.options.errorHandler;
if (errorHandler) {
try {
var data = errorHandler(error, obj);
resolve(data);
} catch (e) {
reject(e);
}
} else {
reject(error);
}
});
});
}
}], [{
key: "requestUse",
value: function requestUse(handler) {
if (typeof handler !== 'function') throw new TypeError('Interceptor must be function!');
requestInterceptors.push(handler);
}
}, {
key: "responseUse",
value: function responseUse(handler) {
if (typeof handler !== 'function') throw new TypeError('Interceptor must be function!');
responseInterceptors.push(handler);
} // 执行请求前拦截器
}, {
key: "dealRequestInterceptors",
value: function dealRequestInterceptors(ctx) {
var reducer = function reducer(p1, p2) {
return p1.then(function () {
var ret = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
ctx.req.url = ret.url || ctx.req.url;
ctx.req.options = ret.options || ctx.req.options;
return p2(ctx.req.url, ctx.req.options);
});
};
return requestInterceptors.reduce(reducer, Promise.resolve()).then(function () {
var ret = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
ctx.req.url = ret.url || ctx.req.url;
ctx.req.options = ret.options || ctx.req.options;
return Promise.resolve();
});
}
}]);
return Core;
}();
/**
* 当执行 “取消请求” 操作时会抛出 Cancel 对象作为一场
* @class
* @param {string=} message The message.
*/
function Cancel(message) {
this.message = message;
}
Cancel.prototype.toString = function toString() {
return this.message ? "Cancel: ".concat(this.message) : 'Cancel';
};
Cancel.prototype.__CANCEL__ = true;
/**
* 通过 CancelToken 来取消请求操作
*
* @class
* @param {Function} executor The executor function.
*/
function CancelToken(executor) {
if (typeof executor !== 'function') {
throw new TypeError('executor must be a function.');
}
var resolvePromise;
this.promise = new Promise(function promiseExecutor(resolve) {
resolvePromise = resolve;
});
var token = this;
executor(function cancel(message) {
if (token.reason) {
// 取消操作已被调用过
return;
}
token.reason = new Cancel(message);
resolvePromise(token.reason);
});
}
/**
* 如果请求已经取消,抛出 Cancel 异常
*/
CancelToken.prototype.throwIfRequested = function throwIfRequested() {
if (this.reason) {
throw this.reason;
}
};
/**
* 通过 source 来返回 CancelToken 实例和取消 CancelToken 的函数
*/
CancelToken.source = function source() {
var cancel;
var token = new CancelToken(function executor(c) {
cancel = c;
});
return {
token: token,
cancel: cancel
};
};
function isCancel(value) {
return !!(value && value.__CANCEL__);
}
var request = function request() {
var initOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var coreInstance = new Core(initOptions);
var umiInstance = function umiInstance(url) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var mergeOptions = objectSpread({}, initOptions, options, {
headers: objectSpread({}, initOptions.headers, options.headers),
params: objectSpread({}, getParamObject(initOptions.params), getParamObject(options.params)),
method: (options.method || initOptions.method || 'get').toLowerCase()
});
return coreInstance.request(url, mergeOptions);
}; // 中间件
umiInstance.use = coreInstance.use.bind(coreInstance);
umiInstance.fetchIndex = coreInstance.fetchIndex; // 拦截器
umiInstance.interceptors = {
request: {
use: Core.requestUse
},
response: {
use: Core.responseUse
}
}; // 请求语法糖: reguest.get request.post ……
var METHODS = ['get', 'post', 'delete', 'put', 'patch', 'head', 'options', 'rpc'];
METHODS.forEach(function (method) {
umiInstance[method] = function (url, options) {
return umiInstance(url, objectSpread({}, options, {
method: method
}));
};
});
umiInstance.Cancel = Cancel;
umiInstance.CancelToken = CancelToken;
umiInstance.isCancel = isCancel;
return umiInstance;
};
/**
* extend 方法参考了ky, 让用户可以定制配置.
* initOpions 初始化参数
* @param {number} maxCache 最大缓存数
* @param {string} prefix url前缀
* @param {function} errorHandler 统一错误处理方法
* @param {object} headers 统一的headers
*/
var extend = function extend(initOptions) {
return request(initOptions);
};
/**
* 暴露 fetch 中间件,保障依旧可以使用
*/
var fetch$1 = request({
parseResponse: false
});
var request$1 = request({});
export default request$1;
export { Onion, RequestError, ResponseError, extend, fetch$1 as fetch };