import { InternalAxiosRequestConfig, AxiosPromise, AxiosError } from 'axios' import { buildFullPath, deepCopy, generateRequestHash } from '../utils' import { addCanceller, deleteCalledCancellerByHash, deleteCancellerByHash, hasCalledCancelerRecord } from '../canceller' import { addRequestCanceler, clearCancelerByHash } from '../cancelLastSameRequest' declare const wx: any type WxErr = { errMsg: string errno: string } export default function wxAdapter(config: InternalAxiosRequestConfig): AxiosPromise { // adapter接受的config要完全符合axios的配置规范,然后在这里针对不同的引擎做个性化修改 return new Promise((resolve, reject) => { let requestConfig = {} as any let isAborted = false let requestTask: any = null const { headers, data, params, url, timeout, method, ...rest } = config const requestHash = generateRequestHash(config) const requestHeader = deepCopy(headers) delete requestHeader.Referer // 小程序文档,header中不能有Referer requestConfig.header = requestHeader const requestData = data || params // wx环境,不论get还是post,参数传递的属性名均为data requestConfig.data = deepCopy(requestData) requestConfig.url = buildFullPath(config.baseURL || '', url || '') requestConfig.timeout = timeout requestConfig.method = method?.toUpperCase() requestConfig = { ...requestConfig, ...rest } requestConfig.success = (res: any) => { let response = {} as any const { data: resData, statusCode, header, ...restRes } = res response.data = resData response.status = statusCode response.headers = header response.config = config response = { ...response, ...restRes } const { validateStatus } = response.config if (!response.status || !validateStatus || validateStatus(response.status)) { resolve(response) } else { const errMsg = `Request failed with status code ${response.status}` reject(new AxiosError(errMsg, '', config, requestTask, response)) } } requestConfig.fail = (err: WxErr) => { if (isAborted) { reject(new AxiosError(err.errMsg, AxiosError.ERR_CANCELED, config, requestTask)) } reject(new AxiosError(err.errMsg, err.errno, config, requestTask)) } // 判断是否已经调用了取消函数 if (hasCalledCancelerRecord(requestConfig.cancelKey, requestHash)) { // 已经调用过取消函数了,直接抛出错误即可 reject(new AxiosError('请求在发出之前被主动取消!', AxiosError.ERR_CANCELED, config, requestTask)) // 删除记录 deleteCalledCancellerByHash(requestConfig.cancelKey, requestHash) return } requestTask = wx.request(requestConfig) // 手动取消请求功能 // 设置了cancelKey,但是环境不支持AbortController if ('undefined' === typeof AbortController) { if (requestConfig.cancelKey) { addCanceller(requestConfig.cancelKey, requestHash, () => { isAborted = true requestTask.abort.call(requestTask) deleteCancellerByHash(requestConfig.cancelKey, requestHash) reject(new AxiosError('请求被取消!', AxiosError.ERR_CANCELED, config, requestTask)) }) } // 取消上一个相同URL的get请求功能 if (requestConfig.cancelLastSameUrl && requestConfig.method.toLocaleLowerCase() === 'get') { addRequestCanceler(config.url as string, requestHash, () => { isAborted = true requestTask.abort.call(requestTask) clearCancelerByHash(config.url as string, requestHash) reject(new AxiosError('请求被取消!', AxiosError.ERR_CANCELED, config, requestTask)) }) } } }) } wxAdapter.type = 'wx'