通常情况下, 直接的去使用axios库并不是那么优雅, 使得代码可读性下降, 不易于维护, 所以有了如下对axios的二次封装
// 配置环境变量
process.env.BASE_API = 'your api url';
process.env.REQUEST_TIMEOUT = 30 * 1000;
// utils.js
// 深冻结
export function deepFreeze (o) {
Object.freeze(o);
Object.getOwnPropertyNames(o).forEach(function (prop) {
if (o.hasOwnProperty(prop) &&
o[prop] !== null &&
(typeof o[prop] === 'object' || typeof o[prop] === 'function') &&
!Object.isFrozen(o[prop])) {
deepFreeze(o[prop]);
}
});
return o;
}
// http.js
import axios from 'axios';
import pickBy from 'lodash/pickBy';
import { deepFreeze } from '@/utils';
import { Message } from 'element-ui';
const TOKEN_KEY = 'X-ACCESS-TOKEN';
/**
* 过滤 null, undefined, NaN
*/
function identity (o) {
return !(o === null || o === undefined || (typeof o === 'number' && o != +o));
}
// 全局配置
axios.defaults.baseURL = process.env.BASE_API;
// axios.defaults.baseURL = 'http://127.0.0.1/inx';
axios.defaults.headers = {
// 'X-ACCESS-TOKEN': AUTHENTICATION_KEY
};
// axios.defaults.withCredentials = true;
// axios.defaults.timeout = process.env.REQUEST_TIMEOUT;
// Add a request interceptor
axios.interceptors.request.use(function (config) {
// Do something before request is sent
if (store.getters.token) {
// 让每个请求携带自定义token 请根据实际情况自行修改
config.headers[TOKEN_KEY] = getToken();
}
return config;
}, function (error) {
// for debug
// Do something with request error
return Promise.reject(error);
});
// Add a response interceptor
axios.interceptors.response.use(function (response) {
const res = response.data;
// if the custom code is not 0, it is judged as an error.
if (res.errno !== 0) {
Message.closeAll();
Message({
message: res.msg || 'Error',
type: 'error',
duration: 5 * 1000
});
// 101: Token expired;
if (res.errno === 101) {
// to re-login
// location.reload();
}
return Promise.reject(new Error(res.msg || 'Error'));
} else {
return deepFreeze(res.data);
}
}, function (error) {
// for debug
console.log('err: ' + error);
Message.closeAll();
// Do something with response error
if (error.response) {
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
});
return Promise.reject(error.response.data || error);
} else {
Message({
message: 'Network error',
type: 'error',
duration: 5 * 1000
});
return Promise.reject(new Error('Network error'));
}
});
// axios
export const http = {
get (url = '', params = {}) {
const cb = arguments[arguments.length - 1];
if (arguments.length > 2 && typeof cb === 'function') {
return axios({
method: 'get',
url,
params: pickBy(params, identity)
}).then(function (result) {
cb(null, result);
}).catch(function (err) {
cb(err, null);
});
} else {
return axios({
method: 'get',
url,
params: pickBy(params, identity)
});
}
},
post (url = '', data = {}) {
const cb = arguments[arguments.length - 1];
if (arguments.length > 2 && typeof cb === 'function') {
return axios({
method: 'post',
url,
data: pickBy(data, identity)
}).then(function (result) {
cb(null, result);
}).catch(function (err) {
cb(err, null);
});
} else {
return axios({
method: 'post',
url,
data: pickBy(data, identity)
});
}
},
all (arr) {
return axios.all(arr).then(axios.spread((...args) => args));
},
/**
* Syntactic sugar for invoking a function and expanding an array for arguments.
*
* Common use case would be to use `Function.prototype.apply`.
*
* ```js
* function f(x, y, z) {}
* var args = [1, 2, 3];
* f.apply(null, args);
* ```
*
* With `spread` this example can be re-written.
*
* ```js
* spread(function(x, y, z) {})([1, 2, 3]);
* ```
*
* @param {Function} callback
* @returns {Function}
*/
spread (callback) {
return function wrap (arr) {
return callback.apply(null, arr);
};
}
};
export const headers = function () {
return {
[TOKEN_KEY]: getToken()
};
};
export const request = axios;
export default { http, headers, request };
// Use http.js
import { http } from 'http.js;
http.get('/api/user', [params]).then().catch();
http.post('/api/user', [data]).then().catch();
评论