0
点赞
收藏
分享

微信扫一扫

vue 中axios请求的封装和使用

东言肆语 2022-02-11 阅读 116
vue.js前端

首先

npm install axios

其次

在src目录下新建一个utils文件夹,我们的一些封装工具都可以放在这。
然后在utils文件夹下新建一个request.js文件,将aixos请求的封装写到里面:

import axios from 'axios'
import Qs from 'qs'
import store from '@/store'
import router from '@/router'
import filterPath from '@/utils/filterPath'
import {Toast} from 'vant'
import {getToken} from '@/utils/auth'
import {removeToken} from "./auth";
import {isEmptyObject} from '@/utils'


// 创建axios实例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // 跨域请求时发送cookie
  timeout: 25000, // 请求超时的时长
  headers: {'Content-Type': 'application/x-www-form-urlencoded'}, // 默认设置请求头 为FormData 数据格式  (JSON数据格式:application/json)
  method: 'post', // 默认设置'post'请求
  withCredentials: true //跨域请求时是否需要使用凭证  简单讲:跨域请求是否提供凭据信息(cookie、HTTP认证及客户端SSL证明等),也可以简单的理解为,当前请求为跨域类型时是否在请求中协带cookie。
});

// 请求拦截器(对请求数据配置做统一处理)
service.interceptors.request.use(
    //在发送请求之前做些什么
    config => {
      // console.log('baseURL:', config.baseURL, config.type)
      const BASE_PATH = filterPath(config.type);
      config.data = {...config.data};
      if(config.method === 'get'){
        config.params = new URLSearchParams(config.data)
      }
      else{
        // 把JSON 转换为 FormData 格式
        config.data = Qs.stringify(config.data)
      }
      config.baseURL = BASE_PATH;

      // 在发送请求之前做些什么
      if (store.getters.token) {
        // 让每个请求都携带令牌
        // ['Authorization'] 是一个自定义标题键
        // 请根据实际情况修改
        config.headers['Authorization'] = 'Bearer ' + getToken();
      } else {
        config.headers['Authorization'] = 'Basic UGFzc3dvcmQwbyFAIw==';
      }
      return config;
    },

    //对请求错误做些什么
    error => {
      // 处理请求错误
      console.log(error); // for debug(用于调试)
      return Promise.reject(error);
    }
);

// 响应拦截器(对成功请求到数据做处理)
service.interceptors.response.use(
    /**
     * 如果您想获取http信息,如标题或状态
     * Please return  response => response
     */
    /**
     * 通过自定义代码确定请求状态
     * 这里只是一个例子,参考即可
     * 您还可以通过HTTP状态代码来判断状态
     */

    response => {
      const res = response.data;
      if (!isEmptyObject(res)) { //isEmptyObject 是一个封装的方法 用来判断一个对象是否是一个空对象
        if (res == null || res === '') {
          Toast('请求无响应');
          return Promise.reject(new Error({code: '4040', msg: '请求无响应'})) //es6 Promise.reject()方法(返回一个带有拒绝原因的Promise对象)
        }
        else if(res.code === 'E1000') {
          Toast(res.errorText);
          removeToken();
          return Promise.reject(new Error({code: res.code, msg: res.errorText}))
        }
        else if(res.code === 'S1000') {
          // 正常响应处理
          return (res);
        }
        else{
          removeToken();
          Toast('登录已过期,请重新登录');
          return Promise.reject(new Error({code: '4040', msg: '登录已过期,请重新登录'}))
        }
      }
      else{
        return (res)
      }
    },
    error => {
      const data = error.response.data;
      if(!error){
        store.dispatch('user/logout'); //vuex中封装的一个用户注销方法
        router.push(`/login`)
      }
      if(!isEmptyObject(data)){
        if(data.error_description){
          switch(data.error_description){
            case 'Bad client credentials':
              data.error_description = '客户端认证失败';
              break;
            case 'User is disabled':
              data.error_description = '用户不存在';
              break;
            case 'UserDetailsService returned null, which is an interface contract violation':
            case 'Bad credentials':
              data.error_description = '账号或密码错误';
              break;
            case 'User account is locked':
              data.error_description = '用户已被禁用,请联系管理员';
              break;
            default:
              data.error_description = '认证失败'
          }
          Toast(data.error_description)
        }
        else{
          Toast(data.message)
        }
      }
      return Promise.reject(error)
    }
);

export default service

紧接着

在src文件夹里创建一个api文件,在api文件中新建一个user.js文件用于存放请求接口,在user.js中写如下代码,以下为一个登录接口例子。

import request from '@/utils/request'

/**
 * 登录
 */
export function login(data) {
  console.log('data:', data)
  return request({
    type: 'base',
    url: '/a/login',
    method: 'post',
    data
  })
}

然后

我们axios请求封装好之后,引入main.js当中,然后全局注册 api 文件夹下的 请求接口,放到 $request下。

import * as utils from './utils'

const Request = require.context('./api', true, /\.js$/);
let requestList = {};
Request.keys().forEach(v => {
  let requestObj = {...Request(v)};
  requestList = Object.assign(requestList, requestObj)
});
Vue.prototype.$request = requestList;

最后

在项目中通过以下形式调用我们的login接口。

<div @click="goLogin">点击调用login请求</div>
export default{
	name:'login',
	data(){
		return{
		}
	},
	methods:{
		goLogin(){
			const params = {};
			this.$request.login(params).then((res)=>{
				console.log(res)
			}).catch(()=>{
				//console.log(1);
			})
		}
	}
}

以上就是axios的封装和使用,如果有不足的地方还请见谅。

举报

相关推荐

0 条评论