vue - vue项目对axios请求的封装

axios介绍

axios是基于promise的网络请求库,可以在nodejs和浏览器中运行。在服务端axios使用原生的nodejs的http模块,在客户端浏览器中则而是用xmlhttprequests,本质是对XHR的封装,只不过是promise的实现版本;

功能:

  • 从浏览器中创建 XMLHttpRequest
  • 从 node.js 中创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应和转换数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防止 XSRF 攻击

开始封装:

1,新建myAxios.js和backend.js;

myAxios主要是对axios的封装,而backend是对后端状态码的判断;

myAxios.js:

import Axios from 'axios';
import {
    
     ErrorToken, GlobalResponseCode, BusinessResponseCode, ApiResult } from '@/api/backend';
import router from '@/router';

// 全局配置
const axios = Axios.create({
    
    
  timeout: 60 * 1000, // 超时时间 1分钟
  headers: {
    
     'Content-Type': 'application/json;charset=UTF-8' }, // axios默认的请求类型 json类型进行传输
});

/* 请求拦截处理token的情况 请求头里面可以随意添加属性 */
axios.interceptors.request.use((config) => {
    
    
  const token = localStorage.getItem('token');
  if (token) {
    
    
    config.headers.authToken = token;
  }
  return config;
});

// 响应拦截
axios.interceptors.response.use(
  (response) => {
    
    
    // 我们一般在这里处理,请求成功后的错误状态码 例如状态码是500,404,403
    return Promise.resolve(response);
  },
  (error) => {
    
    
    // 服务器响应发生错误时的处理
    Promise.reject(error);
  }
);

/* 定义类 */
/* 注意 get多次相同的请求会出现304  post就不会 */
class MyAxios {
    
    
  // 1,get请求
  get(url, params) {
    
    
    console.log('params', params);
    return this.request(axios.get(url, params));
  }
  // 2,post请求
  post(url, data) {
    
    
    return this.request(axios.post(url, data));
  }
  // 3,put请求
  put(url) {
    
    
    return this.request(axios.put(url));
  }

  /**统一响应封装 */
  async request(axiosRequest) {
    
    
    try {
    
    
      const res = await axiosRequest;// axios请求会返回一个promise所以此处使用await进行接收 如果有异常使用 try catch进行捕获
      // 请求失败的情况
      if (!res.data || res.data.code != '000000') {
    
    
        this.resCodePrompt(res.data.code);
        console.warn('SeverError', res);
        // 处理失败结果
        return new ApiResult().setError(res.data);
      }
      // 请求成功的处理
      return new ApiResult().setSuccess(res.data);

    } catch (error) {
    
    
      // TODO 这里需要验证失败的情况
      const res = error.response;
      // 根据状态吗进行提示
      this.resErrorPrompt(res);
      return new ApiResult().setNetworkError();
    }
  }

  /**效验返回码 */
  resCodePrompt(resCode) {
    
    
    // 判断是否是token的问题
    if (ErrorToken.includes(resCode)) {
    
    
      this.$message({
    
     type: 'error', message: '登录凭证无效,请重新登录' });
      router.push('/login');
    }
    // 判断不是token的问题
    const message = GlobalResponseCode[resCode] || BusinessResponseCode[resCode];
    if (message) {
    
    
      return this.$message({
    
     type: 'error', message: '登录凭证无效,请重新登录' });
    }
  }

  /**错误的返回码处理 */
  resErrorPrompt(res) {
    
    
    if (!res) {
    
    
      this.$message({
    
     type: 'error', message: '网络错误!' });
    } else if (res.status === 404) {
    
    
      this.$message({
    
     type: 'error', message: '找不到资源!' });
    } else if (res.status === 500) {
    
    
      this.$message({
    
     type: 'error', message: '内部错误!' });
    } else {
    
    
      // 其余统一提示状态码
      this.$message({
    
     type: 'error', message: `${
      
      res.status}` });
    }
  }
}

export const myAxios = new MyAxios();

backend.js

/**结果封装 */
export class ApiResult {
    
    
  /**请求是否成功 */
  isSuccess = false;
  /**请求结果状态 */
  stu = RequestStu.success;
  /**状态码 */
  code = '000000';
  /**描述信息 */
  msg = '';
  /**请求结果数据 */
  data = null;

  /**后端返回成功 */
  setSuccess(res) {
    
    
    this.isSuccess = true;
    this.stu = RequestStu.success;
    this.msg = res.msg;
    this.data = res.data;
    this.code = res.code;
    console.log('this:', this);
    return this;
  }

  /** 后端返回失败 */
  setError(res) {
    
    
    this.stu = RequestStu.error;
    this.msg = res.msg;
    this.code = res.code;
    return this;
  }

  /** 网络错误 */
  setNetworkError() {
    
    
    this.stu = RequestStu.networkError;
    return this;
  }
}

/**错误响应吗 关于token验证的 */
export const ErrorToken = ['000002', '000003', '000004'];

/**全局响应码 000000--000100(包括000000和000100)*/
export const GlobalResponseCode = {
    
    
  /**成功*/
  '000000': '成功',
  /**请求失败 */
  '000001': '请求失败',
  /**令牌为空 */
  '000002': '请重新登录',
  /**令牌过期 */
  '000003': '请重新登录',
  /**令牌无效 */
  '000004': '请重新登录',
  /**非法请求 */
  '000005': '非法请求',
  /**参数非法 */
  '000006': '参数非法',
  /**参数为空 */
  '000007': '数据为空',
};

/**关于业务逻辑上的响应码 */
export const BusinessResponseCode = {
    
    
  /**账号不存在 */
  '000101': '账号信息有误,请确认',
  /**图片验证码不一致 */
  '000102': '图片验证码有误',
  /**短信验证码不一致 */
  '000103': '短信验证码错误',
  /**与保单绑定的手机号不一致 */
  '000104': '手机号有误,请确认',
  /**未勾选同意条款 */
  '000105': '请先勾选保单设计须知。',
  /**短信验证码获取频繁 */
  '000106': '短信验证码获取频繁',
  /**修改保单失败 */
  '000107': '修改失败',
  /**添加保单信息失败 */
  '000108': '添加保单信息失败',
  /**保单已存在 */
  '000109': '保单已存在',
  /**内部错误 */
  '000110': '内部错误',
  /**保单设计已完成 */
  '000111': '保单设计已完成',
  /**获取图片信息失败 */
  '000112': '获取图片失败,请刷新重试',
  '000113': '图片保存失败,请重试',
  '000114': '上传文件过大,请重新上传',
  '000115': '文件上传失败,请重新上传',
  '000116': '已参加该活动',
  '000117': '活动已结束',
  '000118': '参加的活动不存在',
};

/**请求状态 */
export const RequestStu = {
    
    
  /** 请求成功 */
  success: 'success',
  /** 请求错误 */
  error: 'error',
  /** 连接失败 */
  networkError: 'networkError',
};

2,使用

1,比如有一个登陆接口 ;我们需要封装一下:

import {
    
     myAxios } from '../myAxios';
const prefix = '/backend'
export default {
    
    
  /*  请求登录接口 get请求  普通的get请求和post请求 */
  queryLogin(mobileNo) {
    
    
    return myAxios.get(`${
      
      prefix}/api/user/login`, mobileNo);
  },
};

2,然后再vue组件中请求这个接口:

 methods: {
    
    
    async handleLogin() {
    
    
      // 非空判断
      if (!this.loginForm.account || !this.loginForm.password) {
    
    
        return this.$message('账号或者密码不能为空!');
      }
      // 调用此接口  解构数据
      const {
    
     isSuccess, data, code } = await api.login.queryLogin({
    
    
        account: 'xinjie1',
        password: '123456789',
      });
      // 请求失败的处理
      if (!isSuccess) {
    
    
        return this.$message({
    
     type: 'error', message: code });
      }
      // 请求成功的处理 data
      console.log(data)
		....
    }
  }

3,vue配置接口代理,解决开发环境中的跨域问题;vue.config.js配置如下:

// 服务端ip  需要代理的地址
const api = 'http://10.11.12.181:26341';
  /* 开发环境跨域情况的代理配置 */
  devServer: {
    
    
    /* 接口代理器设置 可以配置多个*/
    proxy: {
    
    
      '/backend': {
    
    
        // 实际访问的服务器地址
        target: api,
        // 控制服务器收到的请求头中Host字段的值  host就是主机名加端口号  实际上就是欺骗后端服务器
        changeOrigin: true,
        // 是否启用websockets
        ws: false,
        // 重写请求路径  开头是/api的替换为 空串
        pathRewrite: {
    
     '/api': '' },
      },
    },
  },

4,如果是上传文件,需要使用formData,接口封装需要处理一下:

import {
    
     myAxios } from '../myAxios';
const prefix = '/backend'
export default {
    
    
 /* formData 文件上传 */
  uploadImg(policyId, policyNo, file) {
    
    
    const formData = new FormData();
    formData.append('policyId', policyId.toString());
    formData.append('policyNo', policyNo);
    formData.append('uploadFile', file);
    // 添加文件上传的请求头
    const axiosConfig = {
    
    
      headers: {
    
    
        'Content-Type': 'multipart/form-data',
      },
      timeout: 10000, //超时时间
      // 表示允许在向服务器发送前,修改请求数据
      transformRequest: [
        function (data, headers) {
    
    
          return data;
        },
      ],
    };
    return myAxios.post(`${
      
      prefix}/api/user/uploadImg`, formData, {
    
     axiosConfig: axiosConfig });
  },
}
 

猜你喜欢

转载自blog.csdn.net/qq_43886365/article/details/129992793