import qs from 'qs' import type { AjaxInstance, AnyObj, ProxyedAttrs } from './types' import { callCancellerByCancelKey, hasCancelers } from './canceller' /** * 标准化config配置,或根据配置项设置相关的参数 * 该函数返回的配置对象,应该完全符合axios的配置规范 * @param {*} config */ export function normalizeConfig(ctx: AjaxInstance, config: any) { const { headers = {}, sendFormData = false, data = undefined, params = {}, baseUrl = '', baseURL = '', reUseDuration = 300, ...rest } = { ...ctx.$options, ...config } // 数据格式为FormData,修改content-type头,以及修改data格式 const contentType = headers['content-type'] || headers['Content-Type'] || 'application/json' headers['content-type'] = sendFormData ? 'application/x-www-form-urlencoded' : contentType const sendData = sendFormData && typeof data === 'object' && data !== null ? qs.stringify(data) : data // baseUrl,支持两种写法,且用户配置的baseUrl优先级最高 const bUrl = baseUrl || baseURL || ctx.$baseUrl if (typeof reUseDuration !== 'number' || Number.isNaN(reUseDuration)) { throw new Error('ajax配置reUseDuration必须是数字') } return { headers, params, data: sendData, baseURL: bUrl, reUseDuration, ...rest, } } export function addInstanceExtendMethod(ctx: any) { const extend = (source: AnyObj) => { Object.keys(source).forEach((key) => { ctx[key] = source[key] }) } ctx.extend = extend } export function proxyAxiosInstanceAttrs(target: AnyObj, source: S): void { const attrs: ProxyedAttrs[] = ['request', 'interceptors', 'defaults'] // const methods: ProxyedAttrs[] = ['request', 'get', 'post', 'delete', 'head', 'options', 'put', 'patch', 'interceptors']; attrs.forEach((method) => { Object.defineProperty(target, method, { value: source[method], writable: false, }) }) } export function proxyAjaxCanceler(ctx: AjaxInstance) { ctx.canceller = new Proxy( {}, { get(_target, prop: string) { if (!hasCancelers(prop)) { return () => { const str = `ajax.canceller对象上不存在名为${prop}的函数!` console.warn(str) return str } } return () => { callCancellerByCancelKey(prop) } }, } ) }