在VUE开发过程中免不了使用axios,官方的axios使用在项目中使用起来还是不怎么方便的,例如对于异步的处理并不完美、请求参数的加密等。
话不多说,直接上代码:
import axios from "axios";
import store from "store/";
import qs from "qs"; // 序列化传参,以&符号连接
import md5 from "md5"; // 加密方法
import {
AUTH_FAIL
} from "@/store/modules/user/constant";
export const CancelToken = axios.CancelToken;
// 创建axios对象
const instance = axios.create();
instance.defaults.withCredentials = true; // 跨域请求时是否需要使用凭证
// instance.defaults.timeout = 20000; // 指定请求超时的毫秒数(0 表示无超时时间)
function get(url, postedData = {}, otherOptions = {}) {
return networkCall(instance.get(url, postedData, otherOptions));
}
function post(url, postedData = {}, otherOptions = {}) {
const { isLogin } = postedData;
delete postedData.isLogin;
otherOptions.headers = paramEncrypt(postedData);
return networkCall(instance.post(url, postedData, otherOptions), isLogin);
}
function postForm(url, postedData = {}, otherOptions = {}) {
return networkCall(instance.post(url, qs.stringify(postedData), otherOptions));
}
function put(url, postedData = {}, otherOptions = {}) {
return networkCall(instance.put(url, qs.stringify(postedData), otherOptions));
}
function del(url, postedData = {}, otherOptions = {}) {
return networkCall(instance.delete(url, postedData, otherOptions));
}
/** 参数加密 */
function paramEncrypt(params = {}) {
const timestamp = new Date().getTime();
let sign = md5(`zh${JSON.stringify(params)}2019${timestamp}`);
let res = {
timestamp,
sign
};
const token = localStorage.getItem("requestToken");
if (token) {
res.token = token;
}
return res;
}
async function download(url, postedData = {}, otherOptions = {}) {
try {
otherOptions.headers = paramEncrypt(postedData);
const res = await instance.post(url, postedData, {
responseType: "blob", // 服务器响应的数据类型
...otherOptions
});
const { data, headers, code, reason } = res;
if (!data) return;
if (code && code === "-1") {
return Promise.reject({
code,
reason
});
} else if (code && +code === 403) {
store.dispatch({
type: AUTH_FAIL,
reason
});
} else { // 下载成功
const fileName = decodeURI(headers["content-disposition"].split("filename=")[1]);
const fileUrl = window.URL.createObjectURL(new Blob([data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = fileUrl;
link.setAttribute("download", fileName);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(fileUrl);
}
}
catch (error) {
console.error("request exception -> error", error);
return Promise.reject(error);
}
}
async function all(axiosPromiseArray) {
try {
return await Promise.all(axiosPromiseArray);
} catch (error) {
console.info("axios all error", error);
return Promise.reject(error);
}
}
async function networkCall(axiosPromise, isLogin) {
try {
const response = await axiosPromise;
const resData = await response.data;
const { code, reason } = resData;
if (+code === 0) { // 请求成功
if (isLogin) {
localStorage.setItem("requestToken", resData.data.token);
}
return resData.data;
}
else if (+code === 403) { // 验证失败
store.dispatch({
type: AUTH_FAIL,
reason
});
} else { // 请求失败
console.error("request fail -> code: ", code);
return Promise.reject({
code,
reason
});
}
} catch (error) { // 请求异常 status !== 200
console.error("request exception -> error", error);
globalAxiosErrorHandler(error);
return Promise.reject(error);
}
}
function globalAxiosErrorHandler(error) {
const host = window.location.origin;
const { status, statusText } = error.response;
const { method, url } = error.config;
const timestamp = Date.now();
// todos: different dealings;
console.error(`${dateFormat(timestamp)} ${method.toUpperCase()}: ${host}${url} ${status} (${statusText})`);
}
function dateFormat(date, fmt = "yyyy-MM-dd hh:mm:ss") {
if (!date) {
throw new Error(`argument 'date' is required`);
}
if (!(date instanceof Date)) {
date = new Date(date);
}
const o = {
"M+": date.getMonth() + 1, // 月份
"d+": date.getDate(), // 日
"h+": date.getHours(), // 小时
"m+": date.getMinutes(), // 分
"s+": date.getSeconds(), // 秒
"q+": Math.floor((date.getMonth() + 3) / 3), // 季度
"S": date.getMilliseconds() // 毫秒
};
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
}
for (const k in o) {
if (new RegExp(`(${k})`).test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return fmt;
}
export default {
delete: del,
del,
get,
post,
postForm,
put,
all,
download,
CancelToken
};
封装好之后可以这样调用:
import axios from "@/modules/axios";
export default {
components: {},
data() {
return {
loading: false,
data1: [],
data2: []
};
},
computed: {
},
watch: {
},
async mounted() {
this.loading = true;
await this.getData1();
await this.getData2();
this.loading = false;
},
methods: {
async getData1(){
try {
let data = await axios.post("/api/formData/list", {page:1,pageSize:50});
this.data1 = data;
} catch (err) {
err.reason && this.$$message(err.reason);
}
},
async getData2(){
try {
let data = await axios.get("/api/formData/class", {id:1});
this.data2= data;
} catch (err) {
err.reason && this.$$message(err.reason);
}
},
async handleDownload() {
try {
await axios.download(`/api/formData/downloadForm`,{page:1,pageSize:100});
} catch (err) {
err.reason && this.$$message(err.reason);
}
},
}
}
其中关于CancelToken的用法我并没有加上,如果想要优化请求的性能的话请参考这篇文章:
https://www.jianshu.com/p/42d1c58e785e
以上内容仅供参考,如果错漏,请及时指出,感激不尽!!!