vue_axios请求封装、异常拦截统一处理

1、前端网络请求封装、异常统一处理(方法一)

vue中使用axios处理网络请求,避免请求接口代码重复使用,以及各种网络情况造成的异常情况的判断,需要对axios请求进行封装和异常拦截操作;

axios 请求封装
//  引入axios文件包
import axios from 'axios'

// POST 方法封装  (参数处理)
export const postRequest = (url, params) => {
  return axios({
    method: 'post',
    url: url,
    data: params,
    transformRequest: [function (data) {
      let ret = ''
      for (let it in data) {
        ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
      }
      return ret
    }],
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    }
  });
}

// POST 方法封装  (文件上传)
export const uploadFileRequest = (url, params) => {
  return axios({
    method: 'post',
    url: url,
    data: params,
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  });
}

//  GET 方法封装
export const getRequest = (url) => {
  return axios({
    method: 'get',
    url: url
  });
}

//  PUT 方法封装
export const putRequest = (url, params) => {
  return axios({
    method: 'put',
    url: url,
    data: params,
    transformRequest: [function (data) {
      let ret = ''
      for (let it in data) {
        ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
      }
      return ret
    }],
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    }
  });
}

//  DELETE 方法封装
export const deleteRequest = (url) => {
  return axios({
    method: 'delete',
    url: url
  });
}

2)axios请求异常统一处理
// 引入依赖包
import axios from 'axios'
import {Message} from 'element-ui'

//  REQUEST 请求异常拦截
axios.interceptors.request.use(config=> {
 //==========  所有请求之前都要执行的操作  ==============
  return config;
}, err=> {
 //==================  错误处理  ====================
  Message.error({message: '请求超时!'});
  return Promise.resolve(err);
})

//  RESPONSE 响应异常拦截
axios.interceptors.response.use(data=> {
//==============  所有请求完成后都要执行的操作  ==================

// 第一种方式

    // 根据返回的code值来做不同的处理(和后端约定)
    switch (data.code) {
        case '0':
            // exp: 修复iPhone 6+ 微信点击返回出现页面空白的问题
            if (isIOS()) {
                // 异步以保证数据已渲染到页面上
                setTimeout(() => {
                    // 通过滚动强制浏览器进行页面重绘
                    document.body.scrollTop += 1
                }, 0)
            }
            // 这一步保证数据返回,如果没有return则会走接下来的代码,不是未登录就是报错
            return data

        // 需要重新登录
        case 'SHIRO_E5001':
            // 微信生产环境下授权登录
            if (isWeChat() && IS_PRODUCTION) {
                axios.get(apis.common.wechat.authorizeUrl).then(({ result }) => {
                    location.replace(global.decodeURIComponent(result))
                })
            } else {
                // 否则跳转到h5登录并带上跳转路由
                const search = encodeSearchParams({
                    next: location.href,
                })

                location.replace(`/user/login`)
            }

            // 不显示提示消息
            data.description = ''
            break

        default:
    }
    // 若不是正确的返回code,且已经登录,就抛出错误
    const err = new Error(data.description)

    err.data = data
    err.response = response

  // 第二种方式,仅对200和error状态处理
  if (data.status && data.status == 200 && data.data.status == 'error') {
    Message.error({message: data.data.msg});
    return;
  }
  return data;
}, err=> {
//==============  错误处理  ====================
   if (err && err.response) {
        switch (err.response.status) {
            case 400: err.message = '请求错误(400)'; break;
            case 401: err.message = '未授权,请重新登录(401)'; break;
            case 403: err.message = '拒绝访问(403)'; break;
            case 404: err.message = '请求出错(404)'; break;
            case 408: err.message = '请求超时(408)'; break;
            case 500: err.message = '服务器错误(500)'; break;
            case 501: err.message = '服务未实现(501)'; break;
            case 502: err.message = '网络错误(502)'; break;
            case 503: err.message = '服务不可用(503)'; break;
            case 504: err.message = '网络超时(504)'; break;
            case 505: err.message = 'HTTP版本不受支持(505)'; break;
            default: err.message = `连接出错(${err.response.status})!`;
        }
    } else {
        err.message = '连接服务器失败!'
    }
  Message.err( {message: err.message } )
  return Promise.resolve(err);
})

请求出错的时候我执行的是:Promise.resolve(err);,而不是Promise.reject(err);,这样无论请求成功还是失败,在成功的回调中都能收到通知

2、VUE 项目中使用该方法

1)在main.js中导入所有请求方法
//  导入所有请求方法
import {getRequest} from './utils/api'
import {postRequest} from './utils/api'
import {deleteRequest} from './utils/api'
import {putRequest} from './utils/api'

2)将请求方法添加至 Vue.prototype 上
//  向VUE的原型上添加请求方法
Vue.prototype.getRequest = getRequest;
Vue.prototype.postRequest = postRequest;
Vue.prototype.deleteRequest = deleteRequest;
Vue.prototype.putRequest = putRequest;

3)发送请求(请求方法的调用)
//  发送网络请求
this.postRequest('/login', {userName,password}).then(res=> {
        ...
    }
});

4)案例
import Vue from 'vue'
import cypressIndex from '../components/rootVue/cypressIndex'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

//  axios请求的方法引入
import {getRequest} from '../components/utils/settings'
import {postRequest} from '../components/utils/settings'

Vue.use(ElementUI);

//  将axios方法添加到VUE原型上
Vue.prototype.getRequest = getRequest;
Vue.prototype.postRequest = postRequest;
Vue.config.productionTip = false

new Vue({
  el: '#cypressIndex',
  render: h => h(cypressIndex)
})

3、前端网络请求封装、异常统一处理(方法二)

import Axios from 'axios'
import urlObj from '/utils/setting'			//	统一域名存储文件

function Service(){
    //  创建axios
    let AxiosIns = new Axios.create({
        baseURL: urlObj.baseUrl,
		transformRequest: [function (data) {
			let retData = ""
			for (let i in data) {
			retData += i + '=' + data[i] + '&'
			}
			return retData
		}],              
    })
    AxiosIns.defaults.withCredentials = true				//  设置允许携带cookie
    AxiosIns.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'      // 设置请求头(表单形式传递参数)
    
    //封装get方法
    this.get = (url,params) => {
        let res = AxiosIns.get(url,{params}).catch( err=>{
            if( err.request ){
                console.log('请求错误')
            }else if( err.response ){
                console.log('响应错误');
            }else{
                console.log('其他错误');
            }
        })
        res.then( rst =>{
            if( rst.data.code == 401){
                window.location.href = urlObj.loginUrl
                return ;
            }
        })
        
        return res;
    }
    //封装post方法
    this.post = (url,params) => {
        let res = AxiosIns.post(url,params).catch(err => {
            if( err.request ){
                console.log('请求错误');
            }else if( err.response ){
                console.log('响应错误');
            }else{
                console.log('其他错误');
            }
        })
        res.then( rst =>{
            if( rst.data.code == 401){
                window.location.href =  urlObj.loginUrl  
                return ;
            }
        })
        return res;
    }

    //首页列表
    this.firstList = ( params ) => {
        return this.get( url ,params);
    }
    this.firstList = ( params ) => {
        return this.post( url ,params);
    }
}

export default new Service();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值