@10yun/cv-js-utils
Version:
常用 js-utils 工具类库
530 lines (516 loc) • 14.9 kB
JavaScript
/**
* 是否在数组里
* @param key
* @param array
* @param regular
* @return {Boolean|*}
*/
function urlInArray(key, array, regular = false) {
if (regular) {
return !!array.find((item) => {
if (item && item.indexOf('*')) {
const rege = new RegExp('^' + item.replace(/[-\/\\^$+?.()|[\]{}]/g, '\\$&').replace(/\*/g, '.*') + '$', 'g');
if (rege.test(key)) {
return true;
}
}
return item == key;
});
} else {
return array.includes(key);
}
}
function checkUrlParse(need_url, base_url) {
let all_url = '';
// /(http|https):\/\/([\w.]+\/?)\S*/.test(url)
if (need_url.includes('http://') || need_url.includes('https://')) {
all_url = need_url;
} else {
all_url = base_url + need_url;
}
/**
* 使用正则表达式进行过滤
* TODO 过滤除了 https:// 和 http:// 以外的 // 和 /// ,但保留 ? 后面的内容
* all_url = all_url.replace(/^(https?:\/\/[^/]+)\/+/g, '$1/');
*/
/**
*
* 过滤除了 https:// 和 http:// 以外的 // 和 ///
*/
all_url = all_url.replace(/([^:]\/)\/+/g, '$1');
return all_url;
}
// 如果你想重新规定返回的数据格式,那么可以借助 response 参数,如:
const responseField = {
statusName: 'status', // 规定数据状态的字段名称,默认:code
statusCode: 200, // 规定成功的状态码,默认:0
msgName: 'msg', // 规定状态信息的字段名称,默认:msg
countName: 'total', // 规定数据总数的字段名称,默认:count
dataName: 'data' // 规定数据列表的字段名称,默认:data
};
/*
* 收集错误信息
*/
const EnumStatusToTitle = {
400: '请求错误',
400: '无效请求',
401: '未经授权',
402: '支付请求',
403: '拒绝访问',
404: '请求出错',
408: '请求超时',
422: '请求验证',
500: '响应错误',
501: '服务未实现',
502: '网络错误',
503: '服务不可用',
504: '网络超时',
505: 'HTTP版本不受支持'
};
const EnumStatusToMsg = {
400: '参数错误',
401: '没有权限,请变更请求',
402: '支付错误',
403: '检查请求域名是否添加了域名白名单',
404: '未找到该请求',
408: '网络异常,请检查网络设置',
422: '参数验证错误',
504: '请求超时,请刷新重试',
500: '请检查网络或服务器' // 服务器错误
// 服务器异常,请联系管理员
// 没有配置服务器地址
};
export function responseInfoParse(status, message) {
status = parseInt(status);
let lastTitle = '提示';
let lastMsg = '请检查网络或联系管理员'; // 程序异常,
// 状态码 - 匹配 - 标题
if (EnumStatusToTitle[status]) {
lastTitle = EnumStatusToTitle[status];
}
// 状态码 - 匹配 - 信息
if (EnumStatusToMsg[status]) {
lastMsg = EnumStatusToMsg[status];
}
return {
title: lastTitle,
status: status,
message: lastMsg
};
}
class RequestClass {
constructor(options = {}) {
this.flagMap = options.flagMap || {};
this.flagAuth = options.flagAuth || {};
this.flagCurr = '';
this.baseURL = options.baseURL || '';
this.baseMock = options.baseMock || '';
this.requests = Object.assign({}, options.requests || {});
this.requestTemp = {};
this.headers = Object.assign({}, options.headers || {});
this.headerTemp = {};
this.configs = Object.assign({}, options.configs || {});
this.configTemp = {}; // 临时
this.customs = Object.assign({}, options.customs || {}); // 自定义参数
this.customTemp = {}; // 临时
// 需要加密的url
this.encryptURL = options.encryptURL || [];
this.encryptFlag = false;
this.retries = 3;
this.debugState = options.debug || false;
this.requestHandle = null;
/* 新创建 http 实例配置 */
this._initReqHandle(options);
}
debugLog() {
if (this.debugState) {
console.log('[调试]', ...arguments);
}
}
/* 初始化 request 句柄 */
_initReqHandle(options) {
// timeout: options.timeout || 5000, // request timeout
// // 表示跨域请求时是否需要使用凭证;
// // 开启withCredentials后,服务器才能拿到你的cookie
// // 当然后端服务器也要设置允许你获取你开启了才有用
// // withCredentials: true, // 开启跨域身份凭证
// retry: 2
}
/**
* 设置API
*/
setApiFlag(options) {
this.flagMap = options || {};
return this;
}
appendApiFlag(options) {
this.flagMap = Object.assign({}, this.flagMap, options || {});
return this;
}
setApiAuth(options) {
this.flagAuth = options || {};
return this;
}
appendApiAuth(options) {
this.flagAuth = Object.assign({}, this.flagAuth, options || {});
return this;
}
/**
* 设置默认header参数
* @param {Object} options
* @return {Class} this
*/
setDefHeaders(options) {
this.headers = Object.assign({}, this.headers, options || {});
return this;
}
setHeaders(options) {
this.headerTemp = Object.assign({}, this.headerTemp, options || {});
return this;
}
getHeaders() {
return this.headers;
}
/**
* 设置默认requests参数
* @param {Object} options
* @return {Class} this
*/
setDefRequests(options) {
this.requests = Object.assign({}, this.requests, options || {});
return this;
}
setRequests(options) {
this.requestTemp = Object.assign({}, this.requestTemp, options || {});
return this;
}
/**
* @function setOptions 设置临时配置
* @param {Object} options - 参数
* @return {Class} this
*/
setOptions(options = {}) {
this.configTemp = Object.assign({}, this.configTemp, options || {});
return this;
}
/**
* @function setCustom 设置临时自定义参数
* @param {Object} options - 参数
* @return {Class} this
*/
setCustom(options) {
this.customTemp = Object.assign({}, this.customTemp, options || {});
return this;
}
/**
* 设置 signal
*/
setSignal(signal) {}
/**
* 加密
*/
encrypt() {
this.encryptFlag = true;
return this;
}
__encryp_parse(url) {
let encryptFlag = false;
if (this.encryptURL && urlInArray(url, this.encryptURL, true)) {
encryptFlag = true;
}
if (this.encryptFlag) {
encryptFlag = true;
}
if (encryptFlag) {
// 是 Windows Xp, Vista, 7, 8 系统,不支持加密
const userAgent = window.navigator.userAgent;
if (
/Windows NT 5.1|Windows XP/.test(userAgent) ||
userAgent.indexOf('Windows NT 6.0') !== -1 ||
userAgent.indexOf('Windows NT 6.1') !== -1 ||
userAgent.indexOf('Windows NT 6.2') !== -1
) {
encryptFlag = false;
}
}
return encryptFlag;
}
cancelRequest(requestId) {
if (!requestId) {
return 0;
}
let __ajaxList = [];
let num = 0;
__ajaxList.forEach((val, index) => {
if (val.id === requestId) {
num++;
if (val.request) {
val.request.abort();
}
}
});
if (num > 0) {
__ajaxList = __ajaxList.filter((val) => val.id !== requestId);
}
return num;
}
/**
* 请求方式
*/
__parse_method_type(type) {
let last_type = type;
return last_type;
}
/**
* 调用 API 统一 请求 方法
*
* @author ctocode-zhw
* @version 2018-12-20
* @param apiUrl 不需要域名,域名统一拼接,只填写相关请求接口 【必须】
* @param reqData 提交参数
* @return
*
*/
async apiAll(type, apiUrl, reqData) {
let request_url = checkUrlParse(apiUrl, this.baseURL);
/**
* 判断是否加密
*/
let encryptFlag = this.__encryp_parse(apiUrl);
/**
* 最后 type
*/
let last_type = this.__parse_method_type(type);
/**
* url是否需要鉴权
*/
let curr_auth_str = this.flagAuth[this.flagCurr] || null;
let auth_data = {};
if (curr_auth_str) {
auth_data = curr_auth_str.split(',').reduce((acc, pair) => {
const [key, value] = pair.split('=');
acc[key] = value;
return acc;
}, {});
}
/**
* 合并变量
*/
let mergeHeaders = Object.assign({}, this.headers, this.headerTemp, {});
let mergeRequests = Object.assign({}, this.requests, this.requestTemp, reqData || {});
let mergeConfigs = Object.assign({}, this.configs, this.configTemp, {});
let mergeCustoms = Object.assign({}, this.customs, this.customTemp, {
flag: this.flagCurr,
auth: auth_data,
time: Math.floor(Date.now() / 1000) // 当前时间戳(秒)
});
// 1. 执行请求拦截器
// 2. 发起请求
let responseInfo = {};
if (last_type == 'UPLOAD') {
mergeHeaders['Content-Type'] = 'multipart/form-data';
} else if (last_type == 'DOWNLOAD') {
/* 文件下载 */
} else if (last_type == 'MOCK') {
} else {
let otherMethod = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];
if (!otherMethod.includes(last_type)) {
console.error('类型错误:', last_type);
return {};
}
return this.ExternalRequestFunc(request_url, {
// baseURL: this.baseURL || '',
method: last_type,
params: mergeRequests,
headers: mergeHeaders
// headers: {
// 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
// 'Accept': 'application/json, text/javascript, */*; q=0.01',
// }
})
.then((response) => {
const responseError = response?.error._rawValue || null;
const responseData = response?.data._rawValue || null;
const responseStatus = response?.status._rawValue || '';
if (responseStatus == 'error') {
return this.netResponseError({
status: 500,
message: responseStatus
});
}
if (responseData && responseStatus == 'success') {
return this.netResponseOK({
status: 200,
data: responseData,
message: responseStatus
});
}
})
.catch((error) => {
return Promise.reject(error);
});
}
}
flagMockPost() {
const argumentsArr = arguments;
return this.unifyApi('flag', 'MOCK', argumentsArr);
}
flagMockGet() {
const argumentsArr = arguments;
return this.unifyApi('flag', 'MOCK', argumentsArr);
}
urlMockPost() {
const argumentsArr = arguments;
return this.unifyApi('url', 'MOCK', argumentsArr);
}
urlMockGet() {
const argumentsArr = arguments;
return this.unifyApi('url', 'MOCK', argumentsArr);
}
/**
* GET 请求
*/
flagGet() {
const argumentsArr = arguments;
return this.unifyApi('flag', 'GET', argumentsArr);
}
urlGet() {
const argumentsArr = arguments;
return this.unifyApi('url', 'GET', argumentsArr);
}
/**
* POST 请求
*/
flagPost() {
const argumentsArr = arguments;
return this.unifyApi('flag', 'POST', argumentsArr);
}
urlPost() {
const argumentsArr = arguments;
return this.unifyApi('url', 'POST', argumentsArr);
}
/**
* PUT 请求
*/
flagPut() {
const argumentsArr = arguments;
return this.unifyApi('flag', 'PUT', argumentsArr);
}
urlPut() {
const argumentsArr = arguments;
return this.unifyApi('url', 'PUT', argumentsArr);
}
/**
* PATCH 请求
*/
flagPatch() {
const argumentsArr = arguments;
return this.unifyApi('flag', 'PATCH', argumentsArr);
}
urlPatch() {
const argumentsArr = arguments;
return this.unifyApi('url', 'PATCH', argumentsArr);
}
/**
* DELETE 请求
*/
flagDel() {
const argumentsArr = arguments;
return this.unifyApi('flag', 'DELETE', argumentsArr);
}
urlDel() {
const argumentsArr = arguments;
return this.unifyApi('url', 'DELETE', argumentsArr);
}
/* 文件上传通用 */
flagUpload() {
const argumentsArr = arguments;
return this.unifyApi('flag', 'UPLOAD', argumentsArr);
}
urlUpload() {
const argumentsArr = arguments;
return this.unifyApi('url', 'UPLOAD', argumentsArr);
}
/* 图片上传通用 */
flagUpImg() {
const argumentsArr = arguments;
return this.unifyApi('flag', 'UPLOAD', argumentsArr);
}
urlUpImg() {
const argumentsArr = arguments;
return this.unifyApi('url', 'UPLOAD', argumentsArr);
}
/**
* 统一请求
*/
unifyApi(flagOrUrl, methodType, argumentsArr) {
let _this = this;
let argNum = argumentsArr.length || 0;
if (argNum <= 0 || argNum > 3) {
let errorMsg = `-- ${methodType} : 参数为(1-3)个---`;
return new Promise((resolve, reject) => {
return reject({ message: errorMsg });
});
}
let apiUrl = '';
let apiUrlNoMsg = '';
if (flagOrUrl == 'flag') {
let apiFlag = argumentsArr[0];
if (typeof apiFlag === 'string') {
apiFlag = apiFlag || '';
apiUrl = apiFlag == '' ? '' : this.flagMap[apiFlag] || '';
}
apiUrlNoMsg = ' flag' + methodType + ':传入的标示 { ' + `${apiFlag}` + ' },未匹配到 apiUrl ';
this.flagCurr = apiFlag;
}
if (flagOrUrl == 'url') {
apiUrl = argumentsArr[0];
if (typeof apiUrl === 'string') {
apiUrl = apiUrl || '';
}
apiUrlNoMsg = ' 未匹配到 apiUrl ';
}
if (apiUrl == '') {
return new Promise((resolve, reject) => {
return reject({ message: apiUrlNoMsg });
});
}
// 如果传回一个
if (argNum == 1) {
return function (reqData) {
return _this.apiAll(methodType, apiUrl, reqData);
};
} else if (argNum == 2 || argNum == 3) {
let reqData = {};
let arg2Val = argumentsArr[1];
let arg2Type = Object.prototype.toString.call(arg2Val);
// let argType2_2 = typeof argumentsArr[1] === 'object';
if (arg2Type === '[object String]' || arg2Type === '[object Number]') {
let isEndIdStr = String(arg2Val).trim();
if (/^\d+$/.test(isEndIdStr)) {
if (!apiUrl.endsWith('/')) {
apiUrl += '/';
}
apiUrl += isEndIdStr; // 拼接时保留大整数精度
}
if (argNum == 3) {
let arg3Val = argumentsArr[2];
let arg3Type = Object.prototype.toString.call(arg3Val);
if (arg3Type === '[object Object]') {
reqData = arg3Val || {};
}
}
} else if (arg2Type === '[object Object]') {
reqData = arg2Val || {};
} else if (arg2Type === '[object FormData]') {
reqData = arg2Val || new FormData();
}
return _this.apiAll(methodType, apiUrl, reqData);
} else {
return new Promise((resolve, reject) => {
return reject({ message: ' 请求错误 ' });
});
}
}
}
export default RequestClass;