0. 缘起
在下从初学者开始,就对这两员大将一直很是胆战心惊。但今天因为一些事情的发生,也为了坚实基础,所以写下这篇文章以备后用。
1. 官方介绍
使用说明 · Axios 中文说明 · 看云 (kancloud.cn)
我挺喜欢这篇看云的官网axios介绍文章,另一个版本的蓝白配色,看的我眼睛要瞎了,不爽。为什么把官网文章放这么前面呢,因为很多时候我懵逼了去搜索引擎搜,搜到的东西都是些奇奇怪怪的,甚至内容毫无关联的标题党。这种情况下,只有官网文本是最可靠的。
2. 易混淆点
params与data
官网说明
// `params` 是即将与请求一起发送的 URL 参数 // 必须是一个无格式对象(plain object)或 URLSearchParams 对象 params: { ID: 12345 },
// `data` 是作为请求主体被发送的数据 // 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH' // 在没有设置 `transformRequest` 时,必须是以下类型之一: // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams // - 浏览器专属:FormData, File, Blob // - Node 专属: Stream data: { firstName: 'Fred' },
比如我有个GET方法,要的参数是[query(string) ]code,
// 组件中要获取信息
await getEnterpriseKind({ code: temp.industryType }).then((res) => {
bef = res.data.name;
});
// /api/index.js调用时
// Get Enterprise Kind From Number/Letter
export function getEnterpriseKind(data) {
return get('/interfacePosition', data, BASEURL)
}
再比如我有个POST 方法,要的参数query(string)
x2 userName password
, query(integer)
platform
// Login
export function loginAccount(account) {
return post('/interfacePosition', {}, { username: account.userName, password: account.password, platform: account.platform }, BASEURL)
}
有没有注意到特殊的地方?看,POST方法在地址后面有个空对象,那这是为嘛呢?看文档就明白,POST有个DATA,这个空对象就是给DATA预留的位置。如果不填这个空对象,后面的就会成为DATA内容,发送了错误的数据。
DATA所在位置就是BODY内,所需参数类型为body(PageDataQuery)
import { download, get, post } from '@/utils/axios';
import store from '@/store/index';
const baseUrl = "/api";
// 获取页面数据
export function getPageData(filter) {
if (store.state.version === 1) {
return post('/v1/webui/pageData', filter, {}, baseUrl);
} else {
return post('/v2/webui/pageData', filter, {}, baseUrl);
}
}
综上所述 get: query
post: data query
3. 关于axios封装[普通版本]
/**
* axios 配置
*/
/* eslint-disable */
import axios from "axios";
import router, { resetRouter } from "@/router";
import store from '@/store'
// 设置全局头信息
axios.defaults.headers["Content-Type"] = "application/json;charset=UTF-8";
// 全局设置超时时间
axios.defaults.timeout = 1800000;
axios.defaults.baseURL = "/api";
// 请求路由拦截
axios.interceptors.request.use(
function (config) {
if (sessionStorage.getItem("token")) {
config.headers["Authorization"] = sessionStorage.getItem("token");
}
if (sessionStorage.getItem("classifyId")) {
config.headers["classifyId"] = sessionStorage.getItem("classifyId");
}
return config;
},
function (error) {
return Promise.reject(error);
}
);
// 响应拦截
axios.interceptors.response.use(
function (response) {
if (response.status === 200) {
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
},
function (err) {
const { status } = err.response ? err.response : { status: "" };
if (err && err.response) {
switch (status) {
case 400:
err.message = "请求错误(400)";
break;
case 401:
err.message = "未授权,请重新登录(401)";
resetRouter();
store.commit("SET_ROUTERS", []);
router.push("/login");
break;
case 403:
err.message = "拒绝访问(403)";
break;
case 404:
err.message = "请求出错(404)";
break;
case 405:
err.message = "请求未允许(405)";
break;
case 408:
err.message = "请求超时(408)";
break;
case 500:
err.message = "服务器错误(500)";
break;
case 501:
err.message = "服务未实现(501)";
break;
case 502:
err.message = "网络错误(502)";
break;
case 503:
err.message = "服务不可用(503)";
break;
case 504:
err.message = "网络超时(504)";
break;
case 505:
err.message = "HTTP版本不受支持(505)";
break;
default:
err.message = `连接出错(${err.response.status})!`;
}
} else {
err.message = "连接服务器失败!";
}
return Promise.reject(err);
}
);
// 封装请求方法
export function get(url, params, baseURL = "") {
let config = {};
config.params = params;
baseURL && (config.baseURL = baseURL);
return new Promise((resolve, reject) => {
axios
.get(url, config)
.then(res => {
resolve(res.data);
})
.catch(err => {
resolve({ success: false, message: err.message });
});
});
}
export function del(url, params, baseURL = "") {
let config = {};
config.params = params;
baseURL && (config.baseURL = baseURL);
return new Promise((resolve, reject) => {
axios
.delete(url, config)
.then(res => {
resolve(res.data);
})
.catch(err => {
resolve({ success: false, message: err.message });
});
});
}
export function post(url, params, query = {}, baseURL = "") {
let config = {};
config.params = query;
baseURL && (config.baseURL = baseURL);
return new Promise((resolve, reject) => {
axios
.post(url, typeof params === "object" ? JSON.stringify(params) : params, config)
.then(res => {
resolve(res.data);
})
.catch(err => {
resolve({ success: false, message: err.message });
});
});
}
export function put(url, params, query = {}, baseURL = "") {
let config = {};
config.params = query;
baseURL && (config.baseURL = baseURL);
return new Promise((resolve, reject) => {
axios
.put(url, typeof params === "object" ? JSON.stringify(params) : params, config)
.then(res => {
resolve(res.data);
})
.catch(err => {
resolve({ success: false, message: err.message });
});
});
}
// 并发请求
export function all() {
let userPromise = Array.prototype.slice.apply(arguments);
return new Promise((resolve, reject) => {
axios
.all(userPromise)
.then(results => {
resolve(results);
})
.catch(() => {
reject(arguments);
});
});
}
// 下载
export function download(url, params, fileName, baseURL = "", isPost = true) {
let file = fileName;
return new Promise((resolve, reject) => {
let promise = isPost ? axios.post(url, null, { params: params, responseType: "blob", baseURL: baseURL })
: axios.get(url, { params: params, responseType: "blob", baseURL: baseURL });
promise.then(response => {
const blob = new Blob([response.data]);
const aEle = document.createElement("a"); // 创建a标签
const href = window.URL.createObjectURL(blob); // 创建下载的链接
aEle.href = href;
aEle.download = file; // 下载后文件名
document.body.appendChild(aEle);
aEle.click(); // 点击下载
document.body.removeChild(aEle); // 下载完成移除元素
window.URL.revokeObjectURL(href); // 释放掉blob对象
resolve("success");
})
.catch(err => {
reject(err.message);
});
});
}
4. 进阶级别的axios封装
vue-admin-beautiful后台管理框架中的axios封装很精致,可以学习。
vue-admin-beautiful: vue-admin-beautiful 是一款前端开发框架,vue 学习搭框架必备,集合了所有的 vue 技术栈 (gitee.com)
5. 地址BUG
新鲜的一个BUG,连了后端小伙伴的地址,他却说没连到。我百思不得其解,问了问组长,组长过来1看,问题出在重复定义地址指向了。
process.env.VUE_APP_BASEURL = "/system";
process.env.VUE_APP_MAGICBOX = "/xy";
process.env.VUE_APP_YLLTASK = "/system";
proxy: {
[`${process.env.VUE_APP_BASEURL}`]: {
target: "http://192.168.20.36:9094/",
ws: true,
changeOrigin: true,
timeout: 30 * 60 * 1000,
pathRewrite: {
[`^${process.env.VUE_APP_BASEURL}`]: ""
}
},
[`${process.env.VUE_APP_YLLTASK}`]: {
target: "http://192.168.20.36:9091",
ws: true,
changeOrigin: true,
timeout: 30 * 60 * 1000,
pathRewrite: {
[`^${process.env.VUE_APP_YLLTASK}`]: ""
}
},
}
其中process.env.VUE_APP_BASEURL
与process.env.VUE_APP_YLLTASK
虽然都是/system
的指向地址,却指向了两个位置,而且YLLTASK还在BASEURL下方,所以使用的时YYLTASK的9091。
这种情况就是要么都修改,要么删掉1个地址导向。