【axios统一处理请求响应】
vue使用axios、axios的使用、axios的封装、axios统一处理请求、axios处理响应数据
·
axios统一封装处理请求
封装统一请求和响应数据
重新封装
axios
统一对请求和响应做处理
统一处理请求
统一处理后台返回的数据
统一处理错误信息
axios.js
/**
* HTTP请求统一封装
* api.js 请求封装
* api.js主要是封装了 请求后台的接口
* 首先将封装好了的 api.js 配置到全局使用
*/
import axios from 'axios'
// 导入 element-ui中的弹窗消息组件
import { Message } from 'element-ui'
// 路由router
import router from '@/router'
// import {store, getStore} from '@/store/store'
// let app = store.state;
// 设置超时时间
axios.defaults.timeout = 5000;
// 跨域请求,允许保存cookie
axios.defaults.withCredentials = true;
// axios中请求配置有baseURL选项,表示请求URL公共部分
axios.defaults.baseURL = process.env.SERVICE_URL;
//axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
/**
* 请求拦截器
* 处理后端请求的统一封装
* success请求成功 & error请求失败
*/
axios.interceptors.request.use(config => {
// 从sessionStorage中获取token
let tokenStr = window.sessionStorage.getItem('tokenStr');
// console.log("======axios======")
// console.log(tokenStr)
// 如果存在token 请求头中携带这个token
if (tokenStr) {
config.headers['Authorization'] = tokenStr;
}
console.log("======请求拦截器=====");
console.log(config);
return config;
}, error => {
console.log("======请求拦截器出错=====");
return console.log(error);
})
/**
* 响应拦截器
* 处理后端响应数据的统一封装
* success请求成功 & error请求失败
*/
axios.interceptors.response.use(success => {
console.log("=======后台返回的数据======");
console.log(success.data);
//此处的success是成功请求到后端接口,并不是请求数据成功了
if (success.status && success.status == 200) {
// 成功调用到后台 500是业务逻辑错误,401是资源找不到,403是权限不足,还有很多状态码,此处省略...
if (success.data.code == 500 || success.data.code == 401 || success.data.code == 403) {
//success.data.message是后台返回的错误信息
Message.error({ message: success.data.message });
return;
}
// 不包含500,401,403...错误信息,则认为成功,有数据就进入下一个判断
if (success.data) {
// 判断是否存在提示信息,存在则弹出提示,否则不弹出提示
if (success.data.message) {
Message.success({ message: success.data.message });
}
return success.data;
}
// 判断后端返回的数据及状态码,后端所有自定义错误状态码均为‘E’开头
let cde = success.data.code + "";
// 若状态码为‘E’开头,则直接返回错误信息,不再继续执行
if (cde.startsWith("E")) {
return Message.error({ message: success.data.msg });
}
// 后端默认自定义的响应成功状态码为'00000',
if (success.data.code == "00000") {
// 响应成功,判断是否有后端返回的提示信息,有则弹出提示,并返回数据
if (success.data.msg) {
Message.success({ message: success.data.msg });
}
return success.data;
}
// 如果状态码不为‘E’或者‘00000’,可能为其他状态码,并且返回的有数据,则返回数据
if (success.data) {
// 判断是否有后端返回的提示信息
if(success.data.msg){
Message.success({ message: success.data.msg });
}
return success.data;
}
}
// 返回后台响应的数据
console.log("=======返回后台响应的数据======");
console.log(success.data);
return success.data;
}, error => {
// error错误信息是没有访问到后端接口,在发送请求时报错
if (error.response.code == 504 || error.response.code == 404) {
return Message.success({
message: '服务器出错,请联系管理员!'
});
} else if (error.response.code == 403) {
return Message.success({
message: '权限不足,请联系管理员!'
});
} else if (error.response.code == 401) {
return Message.success({
message: '尚未登录,请先登录!'
});
// 此处的'/'是根路径,replace是将路径直接替换为新定义的路径
router.replace('/'); // eg: /login-->登录页面
} else {
// 如果响应的有提示信息 则弹出提示信息
if (error.response.data.message) {
return Message.success({
message: error.response.data.message
});
} else {
// 没有响应提示信息 则弹出自定义信息
return Message.success({
message: '未知错误!'
});
}
}
return; // 出错直接返回
});
/* 统一前置路径 */
let baseUrl = '';
/**
* axios请求函数统一封装
*/
export default {
GET: function(url, data) {
console.log("=======get=======");
console.log(url);
console.log(data);
return new Promise((resolve, reject) => {
axios.get(url, data)
.then(resp => {
// resolve(resp.result);
resolve(resp);
}, err => {
reject(err)
})
})
},
POST: function(url, data) {
console.log("=======post=======");
console.log(url);
console.log(data);
return new Promise((resolve, reject) => {
axios.post(url, data)
.then(resp => {
// resolve(resp.result);
resolve(resp);
}, err => {
reject(err)
})
})
},
PUT: function(url, data) {
console.log("=======put=======");
console.log(url);
console.log(data);
return new Promise((resolve, reject) => {
axios.put(url, data)
.then(resp => {
// resolve(resp.result);
resolve(resp);
}, err => {
reject(err)
})
})
}
}
在apis
中封装后端请求的接口
首先 引入上述封装好的
axios
调用axios
中封装好的方法,定义后端接口
apis.js
// 引入上述封装好的 axios
import axios from '@/api/axios'
import qs from 'qs'
/**
* 发送短信验证码
* 对应后端的服务接口
*/
export const sendSMS= (data) => axios.POST('/sms/sendSMS',{params:data})
/**
* 获取图片验证码
* 对应后端的服务接口
*/
export const validateCode= (data) => axios.GET('/code/validateCode',data)
/**
* 首页获取轮播图片
* 对应后端的服务接口
*/
export const getImgUrl = (data) => axios.GET('/img/getImgUrl',{params:data})
/**
* 首页获取商品图片数据
* 对应后端的服务接口
*/
export const getWaresImages = (data) => axios.GET('/img/getWaresImages',{params:data})
/**
* 获取商品信息的图片详情
* 对应后端的服务接口
*/
export const getDetailsImgUrl = (data) => axios.GET('/img/getDetailsImgUrl',{params:data})
/**
* 获取验证码
* @param code
* @param phone
*/
export const getVerifyCode = (data) => axios.GET('/send_sms/getVerifyCode',{params:data})
/**
* 获取图片验证码
* @param code
*/
export const getVerifyCodeImg = () => axios.GET('/image/getVerifyCodeImg')
在main中配置全局方法
main.js
中全局挂载封装好的接口
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import VueRouter from 'vue-router'
import store from './store'
import Qs from 'qs';
// 导入element-ui
import ElementUI from 'element-ui'
// 导入样式
import 'element-ui/lib/theme-chalk/index.css';
// 导入axios
import axios from 'axios'
// 引入上述中配置好的 axios.js
import getRequest from '@/api/axios.js'
// 引入上述封装好的后端api接口
import * as $apis from "@/api/apis.js";
// 让vue去使用element-ui
Vue.use(ElementUI);
Vue.use(VueRouter);
Vue.use(router);
// Vue.use(Vuex)
/**
* 全局方法挂载
* 方便调用时的使用
*/
Vue.prototype.$qs = Qs;
// Vue.prototype.$app = $app;
Vue.config.productionTip = false;
// 全局挂载封装好的api(this.$apis.接口)即可调用
Vue.prototype.$apis = $apis;
// 全局挂载axios(this.方法名)即可调用GET、POST、DELETE、PUT
Vue.prototype.axios=axios;
/**
* to:所要跳转的路径信息,eg:点击首页去首页,这里的数据就是去首页的路由信息
* from:从哪个路由来的,eg:从主页点击首页,这里的数据就是主页的路由信息
* next:跳转下一个钩子函数(to中的路径),如果没有next();就不会跳转到下一个路由
* next(false);不会去执行to中的路由,中断操作,返回from中的路由
* next('/');不去执行to中的路由,直接跳转到inext中的路由
*/
router.beforeEach((to,from,next)=>{
// 取出login.vue中设置的数据状态
let islogin = sessionStorage.getItem('isLogin');
// 判断用户所访问的路径,
if(to.path=='/logout'){
// 如果是注销则清空sessionStorage数据
// console.log("=======main--beforeEach======")
// console.log(window.sessionStorage.getItem("tokenStr"));
// window.sessionStorage.clear();
// console.log(window.sessionStorage.getItem("tokenStr"));
sessionStorage.clear();
// 重新跳转到login页面
next({path:'/login'});
// 如果是登录,先判断用户是否登录
}else if(to.path=='/login'){
// 如果状态为空,就到登录页面
if(islogin != null){
// 不为空就跳转到main.vue主页面
next({path:'/index'});
}
// 如果状态为空,说明没登录,则跳转到登录页面
} else if(islogin == null){
// 跳转到登录页面
next({path:'login'});
}else if(to.path=='index'){
next({path:'index'});
}
// 跳转到下一个钩子函数
next();
})
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
vue中使用配置
配置完成之后 接下来去使用刚刚配置好的api
直接在vue
界面中的js
部分中使用配置
<template>
<div class="block">
<el-carousel :interval="2500" arrow="always" height="210px">
<el-carousel-item v-for="(item,index) in imgArr" :key="index">
<el-image :src="item.url" fit="cover" class="auto-img" @click="showDetails(item.id)"></el-image>
</el-carousel-item>
</el-carousel>
</div>
</template>
<script>
export default {
data() {
return {
// 定义数组,接收请求响应回来的数据
imgArr: []
}
},
created() {
let _this = this;
// 直接通过 this.$apis.方法名即可调用到已经封装好了的后台接口
this.$apis.getWaresImages().then(function(data) {
// 后端响应回来的数据
console.log(data.result);
if (data.result) {
// 将后端返回的数据赋值给上述定义好的数组
_this.imgArr = data.result;
}
});
},
methods: {
showDetails(val) {
console.log(val);
// 路由的跳转
this.$router.push({path: '/details',query:{data:val}});
}
}
}
</script>
跨域配置
如果访问后台出现跨域问题而访问失败,不想后台配置跨域,则可以在前台自己配置一下
vue.config.js
/**********
通过nodeJS的转发代理配置
vue中的跨域处理:代理
在主项目中右键-新建-vue.config.js
**********/
// 新建一个代理类
let proxyObj = {};
proxyObj['/'] = {
// ws是WebSocket,false普通代理,也可以做网络代理
ws: false,
// 所代理的目标地址
target: 'http://localhost:80',
// 发送请求头中的host会被设置成target
changeOrigin: true,
// 重写后端的前置路径,如果没有就不需要重写
pathReWrite:{
// 表示不重写
'^/':'/'
}
}
module.exports = {
devServer:{
host: 'localhost', // 前端地址
port: 8080, // 前端的端口
proxy: proxyObj // 代理配置
}
}
// 将devServer中的host和port代理成proxy中所配置参数
更多推荐
已为社区贡献1条内容
所有评论(0)