基于axios封装
axios文档:https://www.kancloud.cn/yunye/axios/234845
源代码
import axios from 'axios'
import { getAuthToken } from './session'
import { Notification } from 'element-ui'
import router from '../router'
// 只显示一个错误提示
let networkError = false
const warn = (message) => {
if (!message) return
if (!networkError) {
networkError = true
Notification.error({
message,
onClose () {
networkError = false
}
})
}
}
export const baseURL = process.env.BACKEND_SERVER
export const CancelToken = axios.CancelToken // 取消请求
const api = axios.create({
baseURL,
timeout: 10000
})
// 添加请求拦截器
api.interceptors.request.use((config) => {
// 带上用户token
const authToken = getAuthToken()
if (authToken) {
config.headers['Authorization'] = 'Bearer ' + authToken
}
// 清除不需要的参数
if (typeof config.params === 'object') {
config.params = JSON.parse(JSON.stringify(config.params)) // 清除与原数据的引用关联
for (const i in config.params) {
if (config.params[i] === undefined ||
config.params[i] === null ||
config.params[i] === '') {
delete config.params[i]
}
}
}
return config
})
// 添加响应拦截器
api.interceptors.response.use(response => response, (err) => {
if (err && err.response) {
switch (err.response.status) {
case 400:
err.message = '请求错误'
break
case 401:
err.message = '未授权,请登录'
router.push({ path: '/login' })
break
case 403:
err.message = '拒绝访问'
break
case 404:
err.message = `请求地址出错: ${err.response.config.url}`
break
case 408:
err.message = '请求超时'
break
case 500:
err.message = '服务器内部错误'
break
case 501:
err.message = '服务未实现'
break
case 502:
err.message = '网关错误'
break
case 503:
err.message = '服务不可用'
break
case 504:
err.message = '网关超时'
break
case 505:
err.message = 'HTTP版本不受支持'
break
default:
}
} else if (err.message === 'Network Error') {
err.message = '网络错误,请稍后再试!'
}
if (err && err.response && err.response.data && err.response.data.message) {
warn(err.response.data.message)
} else {
warn(err.message)
}
return Promise.reject(err)
})
export default api
API
import api from './ api'
// 获取数据
export async function getData (payload) {
return api.get('/xxx', {
params: payload
})
}
// 设置数据
export async function setData(payload) {
return api.post('/xxx, payload)
}
调用方式和axios一致
功能点
当数据请求方式为get时,清除了为空的参数
请求时带上了用户token
对响应的数据,做了统一的错误提示和处理(根据返回的http状态判断)
注意点
目前接口报错之后,都不会往下执行,通过改成以下形式,可解决
import api from './ api'
// 获取数据
export async function getData (payload) {
return api.get('/xxx', {
params: payload
})
.then(data => data)
.catch(() => Promise.resolve({}))
}
疑难解答
问:为什么每次请求之前都会发一次option请求
答:非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求,浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错(可参考http://www.ruanyifeng.com/blog/2016/04/cors)