@fast-china/axios
Version:
Fast Axios 请求工具库.
1 lines • 16.4 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../../../../src/axios/index.ts"],"sourcesContent":["import axios, { AxiosError } from \"axios\";\nimport { isNil, isObject, isString } from \"lodash-unified\";\nimport { createUniAppAxiosAdapter } from \"../uni-adapter\";\nimport { useFastAxios } from \"./fastAxios\";\nimport type { ApiResponse, AxiosOptions, FastAxiosRequestConfig } from \"./types\";\nimport type { AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from \"axios\";\n\nconst axiosOptions: AxiosOptions = {\n\tcancelDuplicateRequest: true,\n\tloading: false,\n\tloadingText: \"加载中...\",\n\tcache: false,\n\tgetMethodCacheHandle: true,\n\tsimpleDataFormat: true,\n\tshowErrorMessage: true,\n\tshowCodeMessage: true,\n\tautoDownloadFile: true,\n\trestfulResult: true,\n};\n\nconst pendingMap = new Map();\n\n/**\n * 生成每个请求的唯一key\n */\nconst getPendingKey = (axiosConfig: AxiosRequestConfig): string => {\n\tlet { data } = axiosConfig;\n\tconst { url, method, params } = axiosConfig;\n\t// response里面返回的config.data是个字符串对象\n\tif (isString(data)) data = JSON.parse(data);\n\treturn [url, method, JSON.stringify(params), JSON.stringify(data)].join(\"&\");\n};\n\n/**\n * 储存每个请求的唯一cancel回调, 以此为标识\n */\nconst addPending = (pendingKey: string, axiosConfig: AxiosRequestConfig): void => {\n\taxiosConfig.cancelToken =\n\t\taxiosConfig.cancelToken ||\n\t\tnew axios.CancelToken((cancel) => {\n\t\t\tif (!pendingMap.has(pendingKey)) {\n\t\t\t\tpendingMap.set(pendingKey, cancel);\n\t\t\t}\n\t\t});\n};\n\n/**\n * 删除重复的请求\n */\nconst removePending = (pendingKey: string): void => {\n\tif (pendingMap.has(pendingKey)) {\n\t\tconst cancelToken = pendingMap.get(pendingKey);\n\t\tcancelToken(pendingKey);\n\t\tpendingMap.delete(pendingKey);\n\t}\n};\n\n/**\n * Http 错误状态码处理\n */\nconst httpErrorStatusHandle = async (error: AxiosError | any): Promise<string> => {\n\tlet message = \"\";\n\t// 其他错误码处理\n\t// 尝试获取 Restful 风格返回Code,或者获取响应状态码\n\tconst code = error?.response?.data?.code || error?.response?.status || error?.code || \"default\";\n\t// 400业务异常\n\t// 500服务器内部错误,可能返回错误信息\n\t// 判断响应类型是否为blob\n\tif (error?.request?.responseType === \"blob\") {\n\t\ttry {\n\t\t\tmessage = JSON.parse(await error?.response?.data?.text())?.message;\n\t\t} catch {\n\t\t\tmessage = error?.response?.data?.message || useFastAxios().errorCode[code];\n\t\t}\n\t} else {\n\t\tmessage = error?.response?.data?.message || useFastAxios().errorCode[code];\n\t}\n\treturn message;\n};\n\n/**\n * 下载文件\n */\nconst downloadFile = (response: AxiosResponse): void => {\n\tif (typeof uni !== \"undefined\") {\n\t\t// 暂不支持\n\t} else {\n\t\tconst blob = new Blob([response.data], { type: \"application/octet-stream;charset=UTF-8\" });\n\t\tconst contentDisposition = response.headers[\"content-disposition\"];\n\t\tconst result = /filename=([^;]+\\.[^.;]+);*/.exec(contentDisposition);\n\t\tconst filename = result[1];\n\t\tconst downloadElement = document.createElement(\"a\");\n\t\tconst href = window.URL.createObjectURL(blob); // 创建下载的链接\n\t\tconst reg = /^\"(.*)\"$/g;\n\t\tdownloadElement.style.display = \"none\";\n\t\tdownloadElement.href = href;\n\t\tdownloadElement.download = decodeURI(filename.replace(reg, \"$1\")); // 下载后文件名\n\t\tdocument.body.appendChild(downloadElement);\n\t\t// 点击下载\n\t\tdownloadElement.click();\n\t\t// 下载完成移除元素\n\t\tdocument.body.removeChild(downloadElement);\n\t\twindow.URL.revokeObjectURL(href);\n\t}\n};\n\n/**\n * 创建 Axios\n * @param axiosConfig axios 请求配置\n */\nconst createAxios = <Output = any, Input = any>(axiosConfig: FastAxiosRequestConfig<Input>): Promise<Output> => {\n\tconst fastAxios = useFastAxios();\n\n\t// 合并选项\n\tconst options = { ...axiosOptions, ...axiosConfig };\n\n\tif (isNil(options.requestCipher)) {\n\t\toptions.requestCipher = fastAxios.requestCipher;\n\t}\n\n\t// 只有Get请求并且开启了简洁响应才可以进行缓存处理,且默认是不存在loading的\n\tif (options.cache && options.method.toUpperCase() === \"GET\" && options.restfulResult && options.simpleDataFormat) {\n\t\t// 如果启用缓存,则默认是不能携带参数的\n\t\tif (options.params) {\n\t\t\tconsole.warn(\"[Fast.Axios] 如果使用 Http Cache,则不能存在任何 'params' 参数\");\n\t\t}\n\n\t\tif (fastAxios.cache?.get) {\n\t\t\tconst cacheRes = fastAxios.cache.get(options.url);\n\t\t\tif (cacheRes) {\n\t\t\t\treturn Promise.resolve(cacheRes);\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// 不满足上述条件,则默认不使用缓存\n\t\toptions.cache = false;\n\t}\n\n\t// 获取请求唯一 Key\n\tconst pendingKey = getPendingKey(axiosConfig);\n\n\tconst timestamp = Date.now();\n\n\t// 创建 Axios 请求\n\tconst Axios = axios.create({\n\t\t/** 如果是 UniApp 则默认使用适配器 */\n\t\tadapter: typeof uni !== \"undefined\" ? createUniAppAxiosAdapter() : undefined,\n\t\tbaseURL: fastAxios.baseUrl,\n\t\ttimeout: fastAxios.timeout,\n\t\theaders: fastAxios.headers,\n\t\tresponseType: \"json\",\n\t});\n\n\t/**\n\t * 请求拦截\n\t */\n\tAxios.interceptors.request.use(\n\t\t(config: InternalAxiosRequestConfig<Input>) => {\n\t\t\t// 删除重复请求\n\t\t\tremovePending(pendingKey);\n\n\t\t\t// 判断是否开启取消重复请求\n\t\t\toptions.cancelDuplicateRequest && addPending(pendingKey, config);\n\n\t\t\t// 自定义请求拦截器\n\t\t\tfastAxios.interceptors?.request(config);\n\n\t\t\t// 判断是否显示loading层\n\t\t\toptions.loading && fastAxios.loading?.show(options.loadingText);\n\n\t\t\tif (config.responseType === \"json\") {\n\t\t\t\t// 请求参数加密\n\t\t\t\tif (options.requestCipher) {\n\t\t\t\t\tfastAxios.crypto?.encrypt(config, timestamp);\n\t\t\t\t} else {\n\t\t\t\t\t// Get请求缓存处理\n\t\t\t\t\tif (options.getMethodCacheHandle && config.method.toUpperCase() === \"GET\") {\n\t\t\t\t\t\tconfig.params = config.params || {};\n\t\t\t\t\t\tconfig.params._ = timestamp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn config;\n\t\t},\n\t\t(error) => {\n\t\t\tconsole.error(\"[Fast.Axios]\", error);\n\t\t\treturn Promise.reject(error);\n\t\t}\n\t);\n\n\t/**\n\t * 响应拦截\n\t */\n\tAxios.interceptors.response.use(\n\t\t(response: AxiosResponse<Output, Input>) => {\n\t\t\t// 删除重复请求标识\n\t\t\tremovePending(pendingKey);\n\n\t\t\t// 关闭loading层\n\t\t\toptions.loading && fastAxios.loading?.close(options);\n\n\t\t\t// 自定义响应拦截器\n\t\t\tif (fastAxios.interceptors?.response) {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = fastAxios.interceptors.response(response, options);\n\t\t\t\t\tif (!isNil(result)) {\n\t\t\t\t\t\treturn Promise.resolve(result);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(\"[Fast.Axios]\", error);\n\t\t\t\t\treturn Promise.reject(error);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (response.config.responseType === \"blob\" || options.method.toUpperCase() === \"DOWNLOAD\") {\n\t\t\t\tif (response.status === 200) {\n\t\t\t\t\t// 判断是否自动下载\n\t\t\t\t\tif (options.autoDownloadFile) {\n\t\t\t\t\t\tdownloadFile(response);\n\t\t\t\t\t}\n\t\t\t\t\t// 这里直接返回\n\t\t\t\t\treturn Promise.resolve(response);\n\t\t\t\t} else {\n\t\t\t\t\tfastAxios.message?.error(fastAxios.errorCode[\"fileDownloadError\"]);\n\t\t\t\t\treturn Promise.reject(response);\n\t\t\t\t}\n\t\t\t} else if (response.config.responseType === \"json\") {\n\t\t\t\tlet responseData = response.data;\n\t\t\t\tif (options.restfulResult) {\n\t\t\t\t\tconst restfulData = responseData as ApiResponse<Output, Input>;\n\t\t\t\t\tconst code: number = restfulData?.code ?? response.status;\n\t\t\t\t\tif (code < 200 || code > 299 || restfulData?.success === false) {\n\t\t\t\t\t\t// 判断是否显示错误消息\n\t\t\t\t\t\tif (options.showCodeMessage) {\n\t\t\t\t\t\t\t// 判断返回的 message 是否为对象类型\n\t\t\t\t\t\t\tif (restfulData?.message) {\n\t\t\t\t\t\t\t\tif (isObject(restfulData?.message)) {\n\t\t\t\t\t\t\t\t\tfastAxios.message?.error(JSON.stringify(restfulData?.message));\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tfastAxios.message?.error(restfulData?.message);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconsole.error(\"[Fast.Axios]\", new AxiosError(restfulData?.message ?? \"服务器内部错误!\"));\n\t\t\t\t\t\treturn Promise.reject(new AxiosError(restfulData?.message ?? \"服务器内部错误!\"));\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// 请求响应解密\n\t\t\t\tif (options.requestCipher) {\n\t\t\t\t\tresponseData = fastAxios.crypto?.decrypt(response, options);\n\t\t\t\t}\n\n\t\t\t\t// 判断是否缓存\n\t\t\t\tif (options.cache && options.restfulResult && options.simpleDataFormat) {\n\t\t\t\t\tfastAxios.cache?.set(options.url, (responseData as ApiResponse<Output, Input>)?.data);\n\t\t\t\t}\n\n\t\t\t\tif (options.simpleDataFormat) {\n\t\t\t\t\treturn Promise.resolve((responseData as ApiResponse<Output, Input>)?.data);\n\t\t\t\t} else {\n\t\t\t\t\treturn Promise.resolve(responseData);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (options.simpleDataFormat) {\n\t\t\t\t\treturn Promise.resolve(response.data);\n\t\t\t\t} else {\n\t\t\t\t\treturn Promise.resolve(response);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tasync (error: AxiosError) => {\n\t\t\t// 删除重复请求标识\n\t\t\tremovePending(pendingKey);\n\n\t\t\t// 关闭loading层\n\t\t\toptions.loading && fastAxios.loading?.close(options);\n\n\t\t\t// 判断请求是否被取消\n\t\t\tif (axios.isCancel(error)) {\n\t\t\t\tconsole.warn(`[Fast.Axios] ${fastAxios.errorCode[\"cancelDuplicate\"]}`);\n\t\t\t\treturn Promise.reject();\n\t\t\t}\n\n\t\t\t// 判断是否断网\n\t\t\tif (!globalThis.navigator.onLine) {\n\t\t\t\tfastAxios.message?.error(fastAxios.errorCode[\"offLine\"]);\n\t\t\t\treturn Promise.reject();\n\t\t\t}\n\n\t\t\t// 自定义响应错误拦截器\n\t\t\tif (fastAxios.interceptors?.responseError) {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = fastAxios.interceptors.responseError(error, options);\n\t\t\t\t\tif (!isNil(result)) {\n\t\t\t\t\t\treturn Promise.reject(result);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(\"[Fast.Axios]\", error);\n\t\t\t\t\treturn Promise.reject(error);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 处理错误状态码\n\t\t\tif (options.showErrorMessage) {\n\t\t\t\tconst message = await httpErrorStatusHandle(error);\n\t\t\t\tfastAxios.message?.error(message);\n\t\t\t}\n\n\t\t\t// 错误继续返回给到具体页面\n\t\t\tconsole.error(\"[Fast.Axios]\", error);\n\t\t\treturn Promise.reject(error);\n\t\t}\n\t);\n\n\treturn Axios(options);\n};\n\nexport const axiosUtil = {\n\t/**\n\t * 请求\n\t * @param axiosConfig axios 请求配置\n\t * @param loading loading配置\n\t */\n\trequest: createAxios,\n\t/**\n\t * 下载文件\n\t */\n\tdownloadFile,\n};\n\nexport * from \"./types/options\";\nexport * from \"./fastAxios\";\n"],"names":["_a","error"],"mappings":"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"}