日常生活中开发Vue的项目总是免不了要封装axios,今天得空索性写个完完整整的axios封装,结合ElementUI组件库的提示功能,实用性还是不错的。
废话少说,代码贴出如下,如有不正确的地方,欢迎指正:
import axios from 'axios'
// 这里的Message是按需导入的,和VantUI的类似,根据自己的需要决定
import { Message } from 'element-ui'
// 错误代码消息提示框
const tip = message => {
Message({
message,
duration: 1000,
type: 'error'
})
}
// 错误代码捕获
const errorHandler = (status) => {
switch (status) {
case 302:
tip('接口重定向')
break
case 400:
tip('请求错误')
break
case 401:
tip('未授权,请重新登陆')
break
case 403:
tip('没有操作权限')
break
case 404:
tip('请求地址出错')
break
case 405:
tip('请求方法不被允许')
break
case 408:
tip('请求超时')
break
case 422:
tip('无法处理的实体')
break
case 500:
tip('服务器错误')
break
case 501:
tip('服务未实现')
break
case 502:
tip('网关错误')
break
case 503:
tip('服务不可用')
break
case 504:
tip('服务暂时无法访问,请稍后再试')
break
case 505:
tip('HTTP版本不受支持')
break
default:
tip('系统错误,请稍候重试')
break
}
}
// 拦截重复的请求
// 重复的请求是指请求方式、请求路径、请求参数都一致的请求
const pendingMap = new Map()
// 生成每个请求唯一的键
function getPendingKey (config) {
let { url, method, params, data } = config
if (typeof data === 'string') {
data = JSON.parse(data)
}
return [url, method, JSON.stringify(params), JSON.stringify(data)].join('&')
}
// 存储每个请求的唯一值
function addPendingKey (config) {
const pendingKey = getPendingKey(config)
config.cancelToken = config.cancelToken || new axios.CancelToken((cancel) => {
if (!pendingMap.has(pendingKey)) {
pendingMap.set(pendingKey, cancel)
}
})
}
// 取出重复请求并且删除
function removePendingKey (config) {
const pendingKey = getPendingKey(config)
if (pendingMap.has(pendingKey)) {
const cancelToken = pendingMap.get(pendingKey)
cancelToken(pendingKey)
pendingMap.delete(pendingKey)
}
}
class HttpRequest {
// 设置基准路径
constructor (baseURL) {
this.baseURL = baseURL
}
// 设置axios的实例配置
getInstanceConfig () {
const config = {
timeout: 10000,
baseURL: this.baseURL,
headers: {
'Content-Type': 'application/json;charset=utf-8'
}
}
return config
}
// 设置拦截器
interceptors (instance) {
// 请求拦截器
instance.interceptors.request.use(config => {
removePendingKey(config)
addPendingKey(config)
// 这里的token是用户登陆之后获取的,现在暂时乱写
const token = 'jxnwejjwsnwjswswxwxdw'
token && (config.headers.Authorization = `Bear ${token}`)
return config
}, error => {
Promise.reject(error)
})
// 响应拦截器
instance.interceptors.response.use(result => {
removePendingKey(result.config)
return Promise.resolve(result.data)
}, error => {
error.config && removePendingKey(error.config)
const { response } = error
if (response) {
errorHandler(response.status)
return Promise.reject(response)
} else {
if (window.navigator.onLine) {
tip('断网了')
} else {
return Promise.reject(error)
}
}
})
}
// 创建请求的实例,也可以发DELETE和PUT等请求
request (options) {
const instance = axios.create()
const newOptions = Object.assign(this.getInstanceConfig(), options)
// 拦截器操作
this.interceptors(instance)
return instance(newOptions)
}
// get请求
get (url, config) {
const options = Object.assign({
method: 'GET',
url: url
}, config)
return this.request(options)
}
post (url, data) {
return this.request({
url,
method: 'POST',
data
})
}
}
export default HttpRequest