axios-api-query
Version:
一个javascript通过api对象模型描述自动生成axios请求实例的插件
238 lines (234 loc) • 7.51 kB
JavaScript
// 拦截器
import qs from 'querystring';
import _has from 'lodash/has';
import _get from 'lodash/get';
import _set from 'lodash/set';
import _uniq from 'lodash/uniq';
import _isEmpty from 'lodash/isEmpty';
import _pick from 'lodash/pick';
import _omit from 'lodash/omit';
import _keys from 'lodash/keys';
import _isFunction from 'lodash/isFunction';
import _spread from 'lodash/spread';
import _isPlainObject from 'lodash/isPlainObject';
import _includes from 'lodash/includes';
import _toLower from 'lodash/toLower';
import _flattenDeep from 'lodash/flattenDeep';
import _isNil from 'lodash/isNil';
import _forEach from 'lodash/forEach';
import validate from './validate.js';
/**
* @desc request前置拦截器
* @param {{}} requestConfig 请求配置参数
* @returns {{}} {}
*/
const requestSuccessFunc = function(requestConfig = {}) {
const enable = _get(requestConfig, 'console_request_enable', false);
if (enable) {
console.info(
'requestInterceptorFunc',
`url: ${_get(requestConfig, 'url', '')}`,
requestConfig
);
}
if (_isFunction(_get(window, 'apiRequestStartHandler', null))) {
// 通知函数定义处-请求开始发送
_spread(_get(window, 'apiRequestStartHandler'))();
}
const method = _get(requestConfig, 'method', 'GET');
let qsData = _get(requestConfig, 'data', {});
const contentType = _get(requestConfig, 'headers.Content-Type', '');
if (
_includes(contentType, 'application/x-www-form-urlencoded') &&
_includes(['post', 'put'], _toLower(method)) &&
!_isNil(qsData) &&
qsData.length > 0
) {
qsData = qs.parse(qsData); // username=&password= -> {"username": "","password": ""}
}
const validateResult = [];
const paramsValidatorRule = _pick(
_get(requestConfig, 'validator', {}),
_keys(_get(requestConfig, 'params', {}))
);
const dataValidatorRule = _pick(
_get(requestConfig, 'validator', {}),
_keys(qsData)
);
const restfulValidatorRule = _pick(
_get(requestConfig, 'restfulValidator', {}),
_keys(_get(requestConfig, 'restful', {}))
);
const headersValidatorRule = _pick(
_get(requestConfig, 'validator', {}),
_keys(
_omit(_get(requestConfig, 'headers', {}), [
'Accept',
'Content-Type',
'api-module-path',
'isLogin',
'isWhite',
'put',
'post',
'patch',
'head',
'common',
'get',
'delete'
])
)
);
if (
_has(requestConfig, 'validator') &&
!_isEmpty(_get(requestConfig, 'params'))
) {
const paramKeys = _keys(_get(requestConfig, 'params'));
if (paramKeys[0] !== '_') {
validateResult.push(
validate(_get(requestConfig, 'params', {}), paramsValidatorRule)
);
}
}
if (_has(requestConfig, 'validator') && !_isEmpty(qsData)) {
validateResult.push(validate(qsData, dataValidatorRule));
}
if (
_has(requestConfig, 'restfulValidator') &&
!_isEmpty(_get(requestConfig, 'restful'))
) {
validateResult.push(
validate(_get(requestConfig, 'restful', {}), restfulValidatorRule)
);
}
if (
_has(requestConfig, 'validator') &&
!_isEmpty(_get(requestConfig, 'headers'))
) {
const headersVal = _omit(_get(requestConfig, 'headers', {}), [
'Accept',
'Content-Type',
'api-module-path',
'isLogin',
'isWhite',
'put',
'post',
'patch',
'head',
'common',
'get',
'delete'
]);
validateResult.push(validate(headersVal, headersValidatorRule));
}
let status = false;
const validateFailMsg = [];
_forEach(validateResult, (result, i) => {
if (_get(result, 'status')) {
status = true;
validateFailMsg.push(_get(validateResult[i], 'msg'));
}
});
if (status) {
if (_isFunction(requestConfig.vdjs_fail_callback)) {
requestConfig.vdjs_fail_callback(_uniq(_flattenDeep(validateFailMsg)));
}
return Promise.reject(new Error());
}
return requestConfig;
};
/**
* @desc response后置拦截器
* @param {{}} response
* @returns {{}}
*/
const responseSuccessFunc = function(response) {
const enable = _get(response, 'config.console_response_enable', false);
if (enable) {
console.info('responseInterceptorFunc:', response);
}
if (_isFunction(_get(window, 'apiRequestEndHandler', null))) {
// 通知函数定义处-请求结束
_spread(_get(window, 'apiRequestEndHandler'))([response]);
}
if (_has(response, 'data.errCode')) {
// 虽然请求的 status 是 200,但是返回 response 不符合要求
// 比如:{"errCode":404,"errMsg":"不存在的api, 当前请求path为 /login, 请求方法为 GET ,请确认是否定义此请求。","data":null}
const callBack = _spread(
_get(window, 'apiRequestInterceptErrorHandler', function() {})
);
callBack([_get(response, 'data.errMsg', '请求异常')]);
return Promise.reject(new Error(_get(response, 'data.errMsg', '请求异常')));
}
if (_get(response, 'status', 200) === _get(response, 'config.status', 200)) {
const data = _get(response, 'data', {});
if (_get(response, 'config.responseType', '') === 'blob') {
// 文件下载返回
return { data, headers: _get(response, 'headers', {}) };
}
return data;
}
const callBack = _spread(
_get(window, 'apiRequestInterceptErrorHandler', function() {})
);
callBack(['返回 response 的 status 值不是 200']);
return Promise.reject(new Error('返回 response 的 status 值不是 200'));
};
/**
* @desc response后置异常拦截器
* @param {{}} responseError
* @returns {Promise}
*/
const responseErrorFunc = function(responseError, instance) {
if (_isFunction(_get(window, 'apiRequestEndHandler', null))) {
// 通知函数定义处-请求结束
_spread(_get(window, 'apiRequestEndHandler'))([responseError]);
}
const response = _get(responseError, 'response', null);
if (
response &&
_isFunction(
_get(responseError, 'response.config.request_error_callback', null)
)
) {
const enable = _get(
responseError,
'response.config.console_response_enable',
false
);
if (enable) {
console.info('responseErrorFunc:', responseError);
}
const callBack = _spread(
_get(responseError, 'response.config.request_error_callback')
);
const status = _get(responseError, 'response.status', null);
if (
_isPlainObject(_get(response, 'config.statusMessage', null)) &&
_has(response, `config.statusMessage.${status}`)
) {
_set(
response,
'statusText',
_get(response, `config.statusMessage.${status}`)
);
}
const error = _pick(_get(responseError, 'response', null), [
'status',
'statusText',
'config'
]);
error.instance = instance;
callBack([
error,
_get(_pick(_get(responseError, 'response', null), ['data']), 'data', {})
]);
}
if (!response) {
const callBack = _spread(
_get(window, 'apiRequestInterceptErrorHandler', function() {})
);
callBack([_get(responseError, 'message', '')]);
}
return Promise.reject(responseError);
};
export { requestSuccessFunc, responseSuccessFunc, responseErrorFunc };