上一篇中具体的说了vue-router的一些内容;今天加上axios实现接口上的控制;接着肯定涉及到状态的管理方面的内容了;
还是先说一下涉及到的一些基础内容吧;
了解一下axios
在了解axios的时候;先简单的说一下咱们常用的ajax;我之前更新过关于ajax-API的一些属性讲解的文章;大家可以看一下;其实底层都是对XHR的封装;[https://www.jianshu.com/p/4522b2a120cf];这个文章是基于JQ的ajax的一些属性的讲解;
-
axios与ajax的一些对比;
首先大家都了解ajax是对XHR的封装;axios;在客户端的使用的时候也是样的;但是axios又对了些api;axios的官方说的和清楚;关于它的优点:
1.浏览器中使用是XMLHttpRequest;但是在node.js中也可以使用和服务端同样的写法;毫无违和感;基础写法都是
const axios = require('axios');
// Make a request for a user with a given ID
axios.get('/user?ID=12345')
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
// Optionally the request above could also be done as
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})
.then(function () {
// always executed
});
// Want to use async/await? Add the `async` keyword to your outer function/method.
async function getUser() {
try {
const response = await axios.get('/user?ID=12345');
console.log(response);
} catch (error) {
console.error(error);
}
}
大家都看到了then;是的;有人这么评价;axios是对ajax使用Promise方法的封装;事实上不是这样的;关于Features中的第三条也提到了支持Promise;
2.关于接下来的一条就是实现拦截使用的功能;Intercept request and response;拦截请求和响应;数据的请求和响应;进行统一拦截;就可以实现权限的控制;
3.剩余的几个功能点都是对功能的加强;修改请求数据和响应数据的格式取消请求;自动处理JSON数据;在客户端支持避免XSRF攻击;大家可以简单了解一下XSRF;最有效的预防方式就是一次有效token;和cookie的key处理;
vue中使用axios;
说过axios的一些功能;开始使用把;
首先安装把;
npm i -D axios
;
然后再main.js中引入;因为接下来要做很多请求拦截和逻辑处理;所以就不要在main.js中处理这些了;
我构建了一个host文件;接下来一一介绍;
首先http.js的内容
/**
* 接口权限
* http配置
*/
import axios from 'axios'
import store from '../store/store'
import * as types from '../store/types'
import router from '../router'
import Vue from 'vue';
const Busvue=new Vue();
// axios 配置
// axios.defaults.timeout = 5000;
// axios.defaults.baseURL = 'https://api.github.com';
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
// http request 拦截器
axios.interceptors.request.use(
config => {
if (store.state.token) {
config.headers.common['token'] = store.state.token;
config.headers.common['Cache-Control'] = 'no-cache';
config.headers.Pragma = 'no-cache';
};
//尝试拦截请求内容;
// var urlStr = config.url;
// console.log(urlStr.substring(7))
// if (urlStr.includes('/testca')){
// var a = urlStr.substring(7)
// config.url = '/testca/api'+a;
// }
// console.log('获取请求实体的内容',config)
return config;
},
err => {
return Promise.reject(err);
});
// http response 拦截器
axios.interceptors.response.use(
response => {
if (typeof response.data.code!="undefined"&&response.data.code==10104023){
Busvue.$message({
message: '无效的token!请重新登陆!',
type: 'error'
});
store.commit(types.LOGOUT);
router.replace({
path: '/login',
query: { redirect: router.currentRoute.fullPath }
});
}else{
return response;
}
},
error => {
if (error.response) {
switch (error.response.status) {
case 401:
// 401 清除token信息并跳转到登录页面
store.commit(types.LOGOUT);
router.replace({
path: '/login',
query: {redirect: router.currentRoute.fullPath}
});
break;
case 403:
Busvue.$message({
message: '您没有该功能使用权限。',
type: 'error'
});
break;
case 504:
Busvue.$message({
message: '网络超时,请重试',
type: 'error'
});
break;
}
}else{
store.commit(types.LOGOUT);
router.replace({
path: '/login',
query: { redirect: router.currentRoute.fullPath }
});
}
// console.log(JSON.stringify(error));//console : Error: Request failed with status code 402
console.log("axios", error);
return Promise.reject(error.response.data);
});
export default axios;
一些状态码肯定要和服务端协商好的;比如;401未登录或登陆过期进入到登陆界面;403无权限;接着做无权限的处理;另外中间vuex进行状态管理;先不说;
apiConfig.js;我们将接口进行了统一的处理;大家也可以使用定义各个modules;然后import;就变成这样的文件处理了;
里面多的listapi.js以及detail.js都是各个页面的view视图层用到的接口;建议大家放在某个文件里面;我是为了让大家看就不细致的搞了
listApi.js
let baseUrl = '/finance';
let baseUrl2='/testca'
module.exports = {
//运营后台2.1版本接口管理;
testapi: [baseUrl+'/customer/admittance/siteCustomers', 'POST'],//获取仓库;
nodeList: [baseUrl2+'/cloudwarehouse/callboard/list','GET']
};
apiConfig.js
let baseUrl = '/finance';
let baseUrl2='/testca'
import listapi from './listapi'
import detailapi from './detail'
let APIS = {};
Object.assign(API,listapi,detailapi)
console.log(APIS)
const getConfig = apiName => APIS[apiName];
export default getConfig;
也是模块化思想吧;
接下来是axiosAjax.js就是方法的暴露吧
import Vue from 'vue';
import getConfig from './apiConfig.js';
const Busvue = new Vue();
//获取数据GET
let getDataaxios=(url, data)=>{
return new Promise((resolve, reject) => {
Busvue.axios({
method: 'GET',
url: url + "?t=" + Date.now(),
headers: {"appCode": "927f951e5e127ea1fb2582695ec7ddff" },
params: data
})
.then(function (res) {
//接口请求回调
resolve(res);
})
.catch(function (error) {
//接口异常
reject(error);
// console.log("接口异常", error);
})
});
};
//获取数据POST
let postDataaxios=(url, data,method)=>{
return new Promise((resolve, reject) => {
Busvue.axios({
method: method.toLowerCase(),
url: url + "?t=" + Date.now(),
headers: { "appCode": "927f951e5e127ea1fb2582695ec7ddff" },
data: data
})
.then(function (res) {
//接口请求回调
resolve(res);
})
.catch(function (error) {
//接口异常
reject(error);
// console.log("接口异常", error);
})
});
};
let axiosAjax=(apiKey,data,fun)=>{
if (getConfig(apiKey)[1].toLowerCase()=='post'||getConfig(apiKey)[1].toLowerCase()=='put'||getConfig(apiKey)[1].toLowerCase()=='delete'){
return postDataaxios(getConfig(apiKey)[0],data,getConfig(apiKey)[1])
}else if(getConfig(apiKey)[1].toLowerCase() == 'get'){
return getDataaxios(getConfig(apiKey)[0],data)
}else{
throw new Error('请输入正确的请求方式!现仅支持GET||POST');
}
};
export default axiosAjax;
/*
var datas={};参数;回调函数;
this.axiosAjax('testapi', datas, this.testHH)
*
*/
最后一步就是在main.js引入axiosAjax.js;然后axios内容就结束了
main.js
import axiosAjax from './host/axiosAjax.js'
Vue.prototype.axiosAjax = axiosAjax;//封装公用API;
具体在各个模块中的使用方式
this.axiosAjax([接口对应的属性名称]).then((res)=>{
//如果使用listApi的第一个接口 在对应的 [接口对应的属性名称]写上testApi;
返回结果;
})
axios结束了
接下来就是关于vue-router的内容了;在axios对权限实现拦截后;vue-router就要对登陆就行拦截了;
router.js
const libraryAd = resolve => require(["@/components/goodsSearch/goodsSearch"],resolve);
const routes = [
{
path: '/libraryAd',
name: 'libraryAd',
meta: {
requireAuth: true,
},
component: libraryAd
}];
Vue.use(VueRouter);
// 页面刷新时,重新赋值token;
我们放在sessionStorage中的原因就是要在用户打开新标签页的时候不在新的登陆状态
if (window.sessionStorage.getItem('token')) {
store.commit(types.LOGIN, window.sessionStorage.getItem('token'));
}
const router = new VueRouter({
mode: 'history',
routes
});
router.beforeEach((to, from, next) => {
sessionStorage.fromRouterpath = from.path;
sessionStorage.toRouterpath = to.name;
if (to.matched.some(r => r.meta.requireAuth)) {
if (store.state.token == "undefined" || store.state.token == null) {
next({
path: '/cloudHouse/login',
query: { redirect: to.fullPath }
});
return;
}
} else {
next();
}
})
export default router;
今天先到这吧;多学习吧;停不下来的;