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中所配置参数

Logo

前往低代码交流专区

更多推荐