/** axios封装
|
* 请求拦截、相应拦截、错误统一处理
|
*/
|
import axios from 'axios'
|
|
// const http = axios.create()
|
|
export default class BaseAxios {
|
/**
|
* constructor 构造函数
|
* @param {Object} conf 实例全局配置,配置项基本同 defaultConf
|
*/
|
constructor(conf = {}) {
|
this.defaultConf = {
|
// baseURL: process.env.VUE_APP_API_HOST,
|
timeout: 30000,
|
method: 'post',
|
headers: {
|
'Content-Type': 'application/json;charset=UTF-8'
|
},
|
withCredentials: true,
|
responseType: 'json'
|
}
|
|
this.specialParamsKeys = [
|
'data',
|
'method',
|
'headers',
|
'withCredentials',
|
'responseType'
|
]
|
this.init(conf)
|
}
|
|
/**
|
* 初始化,合并配置
|
* @param {Object} conf 全局配置
|
*/
|
init(conf) {
|
const { defaultConf } = this
|
this.conf = Object.assign({}, { ...defaultConf }, { ...conf })
|
}
|
|
/**
|
* post 请求处理
|
* @param {String} api 接口地址
|
* @param {Object|String} params 请求参数
|
*/
|
post(api, params = {}, conf = {}) {
|
return this.request(api, params, { method: 'post', ...conf })
|
}
|
|
/**
|
* get 请求处理
|
* @param {String} api 接口地址
|
* @param {Object|String} params 请求参数
|
*/
|
get(api, params = {}, conf = {}) {
|
return this.request(api, params, { method: 'get', ...conf })
|
}
|
|
/**
|
* mixParams 参数混入处理,可供实例后续扩展
|
* @param {Object|String} params 请求参数
|
*/
|
mixParams(params) {
|
const { specialParamsKeys } = this
|
if (typeof params === 'string') {
|
params = { data: params }
|
}
|
if (typeof params === 'object') {
|
// 若参数中包含配置信息,则不需要特殊处理(此时的实际参数为params的data字段)
|
if (!Object.keys(params).some(key => specialParamsKeys.includes(key))) {
|
params = { data: params }
|
}
|
}
|
return params
|
}
|
|
/**
|
* mixConf 合并配置项
|
* @param {Object} conf 请求配置项
|
* @param {Object} params 参数或包含参数的配置项 @example {data: {name: 'someone'}}
|
*/
|
mixConf(conf = {}, params = {}) {
|
return Object.assign(
|
{},
|
{ ...this.conf },
|
{ ...conf },
|
{ ...this.mixParams(params) }
|
)
|
}
|
|
/**
|
* getUrl 获取请求url完整地址
|
* @param {String} api请求地址
|
* @param {Object} mixConf 混入后的请求配置
|
*/
|
getUrl(api, mixConf) {
|
const { method = 'post', baseURL = '', data = {} } = mixConf
|
// 避免/符号重复
|
let url = baseURL === '' ? baseURL : `${baseURL.replace(/\/+$/, '')}/`
|
|
// 如果是完整http路径,则不用拼接baseURL前缀
|
if (api.search(/^https?:\/\//) !== 0) {
|
api = `${url}${api.replace(/^\/+/, '')}`
|
}
|
if (method.toLocaleLowerCase() === 'get') {
|
const str = this.getUrlParams(api, data)
|
api = api.includes('?') ? `${api}&${str}` : `${api}?${str}`
|
}
|
return api
|
}
|
|
/**
|
* getUrlParams 拼接url字符串
|
* @param {String} api 接口地址
|
* @param {Object|String} params 请求参数
|
*/
|
getUrlParams(params) {
|
if (typeof params === 'object') {
|
params = Object.keys(params).reduce((pre, curr) => {
|
const val =
|
typeof params[curr] === 'object'
|
? JSON.stringify(params[curr])
|
: params[curr]
|
pre = pre === '' ? pre : `${pre}&`
|
pre = `${pre}${curr}=${val}`
|
return pre
|
}, '')
|
}
|
return params
|
}
|
|
/**
|
* getParams 根据headers信息,
|
* @param {Object} mixConf 请求配置项
|
*/
|
getParams(mixConf) {
|
let { data = {}, headers = {} } = mixConf
|
Object.keys(headers).forEach(key => {
|
if (key.toLocaleLowerCase() === 'content-type') {
|
// json string
|
if (
|
headers[key].includes('application/json') &&
|
typeof data !== 'string'
|
) {
|
data = JSON.stringify(data)
|
}
|
|
// params
|
if (headers[key].includes('application/x-www-form-urlencoded')) {
|
data = this.getUrlParams(data)
|
}
|
|
// file
|
if (
|
headers[key].includes('multipart/form-data') &&
|
!(data instanceof FormData)
|
) {
|
const formData = new FormData()
|
Object.keys(data).forEach(key => {
|
formData.append(key, data[key])
|
})
|
data = formData
|
}
|
}
|
})
|
return data
|
}
|
|
/**
|
* 请求统一入口
|
* @param {String} api 接口地址
|
* @param {Object|String} params 请求参数
|
* @param {Object} conf 请求配置信息
|
*/
|
request(api, params = {}, conf = {}) {
|
const mixConf = this.mixConf(conf, params)
|
const url = this.getUrl(api, mixConf)
|
const data = this.getParams(mixConf)
|
return this.axios({
|
...mixConf,
|
url,
|
data
|
})
|
}
|
|
/**
|
* 原始axios请求方法
|
* @param {Object} conf 请求配置
|
*/
|
axios(conf = {}) {
|
return axios.create()(conf)
|
}
|
}
|