注: 使用的UI框架是element-ui, 由于封装过程需要使用自定义axios的config,因此使用的axios版本是 0.18.0,有的版本不支持自定义config
解析: 多种ip域名,多种content-type类型的原理, 利用axios的自定义config属性, 获取相应的内容
import axios from 'axios'
import {
ipConfig} from "../ip-map-config";
import {
requestInterceptors} from './interceptors-request'
import {
responseInterceptors} from './interceptors-response'
import messageErrorHint from './message-error-hint'
const server = axios.create({
baseURL: ipConfig.commonIp(), // 默认baseURL
timeout: 50000, // 请求超时时间
withCredentials: true // 表示跨域请求时是否需要使用凭证
});
server.interceptors.request.use(requestInterceptors, error => {
messageErrorHint(error, '客户端响应失败')
return Promise.reject(error)
});
server.interceptors.response.use(responseInterceptors, error => {
messageErrorHint(error, '服务器响应失败')
return Promise.reject(error)
});
export default server;
import {
tokenCookies} from "../cookies";
import {
showFullScreenLoading} from "./loading";
export function requestInterceptors(config) {
// 默认全局Content-Type = application/json;charset=utf-8
// 默认get和options, application/x-www-form-urlencoded;charset=utf-8
if(config.method === 'options' || config.method === 'get') {
config.headers[ 'Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'
}
// 获取token
config.headers['X-Access-Token'] = tokenCookies.getToken() || null
// 配置loading加载
const loadingMessage = config['loadMsg'] || null
loadingMessage && showFullScreenLoading('body', loadingMessage)
return config;
}
import {
tryHideFullScreenLoading} from "./loading";
import messageErrorHint from './message-error-hint'
export function responseInterceptors(response) {
const {
status, data} = response;
const {
success, code = -1} = data;
tryHideFullScreenLoading()
if (status === 200) {
let isSuccess = false;
if (typeof success !== undefined && success) {
isSuccess = true;
} else if (typeof code !== undefined && code === 0) {
isSuccess = true;
}
if (!isSuccess) {
// error handle
messageErrorHint(response, '服务器响应失败')
return Promise.reject(response)
}
// success handle
return response.data.data;
} else {
return Promise.reject(response)
}
}
import {
ipConfig} from "../ip-map-config";
import {
tryHideFullScreenLoading} from "./loading";
import {
MessageError} from "../custom/message";
const messageErrorHint = _.debounce((error, message) => {
let msg = message
tryHideFullScreenLoading()
if (error && error.data) {
msg = error.data.message
// 登录失效,返回登录页,如果同一个系统可以使用 router.push()
error.data.code === -9 && router.push('/login')
}
MessageError(msg, 2000)
}, 300)
export default messageErrorHint
// 全局loading
import {
Loading} from 'element-ui'
import _ from 'lodash'
//loading对象
let loading
// 当前正在请求的数量
let needLoadingRequestCount = 0
// 声明一个对象用于储存请求个数
export const showFullScreenLoading = function (target, message) {
if (needLoadingRequestCount === 0) {
startLoading(target, message)
}
needLoadingRequestCount++
}
function startLoading(target, message) {
// 后面这个判断很重要,因为关闭时加了抖动,此时loading对象可能还存在,
// 但needLoadingRequestCount已经变成0.避免这种情况下会重新创建个loading
if (needLoadingRequestCount === 0 && !loading) {
loading = Loading.service({
lock: true,
text: message || '拼命加载中……',
background: 'rgba(255, 255, 255, 0.5)',
target: target || "body"
})
}
}
export function tryHideFullScreenLoading() {
if (needLoadingRequestCount <= 0) return
needLoadingRequestCount--
needLoadingRequestCount = Math.max(needLoadingRequestCount, 0); //做个保护,给定的一组数字中的最大值
if (needLoadingRequestCount === 0 && loading) {
//防抖:将 300ms 间隔内的关闭 loading 便合并为一次。防止连续请求时, loading闪烁的问题。
tryCloseLoading()
}
}
const tryCloseLoading = _.debounce(() => {
loading.close()
loading = null;
}, 300)
接口使用
// 使用默认ip,和content-type
export function getList(data) {
return request({
method: 'post',
url: 'login',
data
})
}
// 使用自定义的ip和content-type
export function login(data) {
return request({
method: 'post',
url: 'login',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
},
data,
loadMsg: '拼命加载中...',
baseURL: 'http://127.0.0.1:3001/'
})
}