axios对请求各种异常情况处理的封装方法

前端采用了axios来处理网络请求,为了避免在每次请求时都去判断各种各样的网络情况,比如连接超时、服务器内部错误、权限不足等等不一而足,我对axios进行了简单的封装,这里主要使用了axios中的拦截器功能。

封装后的网络请求工具js如下

前端精品教程:百度网盘下载

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

import axios from ‘axios‘

import { Toast } from ‘mint-ui‘

//请求时的拦截

axios.interceptors.request.use(config => {

 return config;

}, err => {

 Toast(‘请求超时!‘ );

 return Promise.resolve(err);

})

//响应时的拦截

axios.interceptors.response.use(data => {

 // 返回响应时做一些处理

 // 第一种方式

 const data = response.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?${search}`)

   }

   // 不显示提示消息

   data.description = ‘‘

   break

  default:

 }

 // 若不是正确的返回code,且已经登录,就抛出错误

 const err = new Error(data.description)

 err.data = data

 err.response = response

 // 第二种方式,我采取的

 if (data.status && data.status == 200 && data.data.status == ‘error‘) {

  Toast(data.data.msg);

  return data;

 }

 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 = ‘连接服务器失败!‘

 }

 Toast(err.message);

 return Promise.resolve(err);

})

//如果需要可以封装一些请求的方法

let base = ‘‘;

export const postRequest = (url, params) => {

 return axios({

  method: ‘post‘,

  url: `${base}${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‘

  }

 });

}

export const uploadFileRequest = (url, params) => {

 return axios({

  method: ‘post‘,

  url: `${base}${url}`,

  data: params,

  headers: {

   ‘Content-Type‘: ‘multipart/form-data‘

  }

 });

}

export const putRequest = (url, params) => {

 return axios({

  method: ‘put‘,

  url: `${base}${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‘

  }

 });

}

export const deleteRequest = (url) => {

 return axios({

  method: ‘delete‘,

  url: `${base}${url}`

 });

}

export const get = (url,params) => {

 return axios({

  method: ‘get‘,

  url: `${base}${url}?`,

  params: params,

  headers:{

   ‘Content-Type‘: ‘application/x-www-form-urlencoded‘,

   ‘Access-Token‘: localStorage.getItem("AccessToken")

  }

 });

}

封装之后的错误信息这个大家一目了然,没啥好说的,唯一要说的是当出错的时候我执行的是:Promise.resolve(err);,而不是Promise.reject(err);

这是什么原因呢?因为封装axios一个重要的目的就是希望能够对错误进行统一处理,不用在每一次发起网络请求的时候都去处理各种异常情况,将所有的异常情况都在工具js中进行统一的处理。但是这种方式也带来一个问题,就是我在发起网络请求的时候,一般都会开启一个进度条,当网络请求结束时,不论请求成功还是失败,我都要将这个进度条关闭掉,而失败的处理我都统一写在工具js里边了,因此就没在请求失败时关闭进度条了,解决这个问题,有两种方案:

前端精品教程:百度网盘下载

1.直接在request的拦截器中开启一个fullscreen的loading,然后在response的拦截器中将其关闭,即我将进度条也封装到工具js中了,但是非常不推荐这种方式,因为这种方式的用户体验非常之差,有兴趣的小伙伴可以自己试一下就知道了。

2.第二种解决方案就是大家看到的,我返回一个Promise.resolve(err),则这个请求不会就此结束,错误的message我已经弹出来了,但是这条消息还是会继续传到then中,也就是说,无论请求成功还是失败,我在成功的回调中都能收到通知,这样我就可以将loading关闭了,比如下面这个登录请求:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

var _this = this;

this.loading = true;

this.postRequest(‘/login‘, {

 username: this.loginForm.username,

 password: this.loginForm.password

}).then(resp=> {

 _this.loading = false;

 if (resp && resp.status == 200) {

 _this.getRequest("/config/hr").then(resp=> {

  if (resp && resp.status == 200) {

  var data = resp.data;

  _this.$store.commit(‘login‘, data);

  var path = _this.$route.query.redirect;

  _this.$router.replace({path: path == ‘/‘ || path == undefined ? ‘/home‘ : path});

  }

 })

 }

添加Vue插件

由于我对axios进行了封装,因此在每一个需要使用axios的地方,都需要导入相应的请求,略显麻烦,参考https://cn.vuejs.org/v2/guide/plugins.html,我将请求方法挂到Vue上,具体操作如下:

1.在main.js中导入所有的请求方法,如下:

?


1

2

3

4

import {get} from ‘./utils/api‘

import {postRequest} from ‘./utils/api‘

import {deleteRequest} from ‘./utils/api‘

import {putRequest} from ‘./utils/api‘

2.把它们添加到 Vue.prototype 上,如下:

前端精品教程:百度网盘下载

?


1

2

3

4

Vue.prototype.getRequest = getRequest;

Vue.prototype.postRequest = postRequest;

Vue.prototype.deleteRequest = deleteRequest;

Vue.prototype.putRequest = putRequest;

如此之后,以后再需要发送网络请求,就不需要导入api了,直接通过下面这种方式即可:

Post方法:

?


1

2

3

4

5

6

7

this.postRequest(‘/login‘, {

 username: this.loginForm.username,

 password: this.loginForm.password

}).then(resp=> {

 ...

 }

});

GET方法:

?


1

2

3

4

5

6

7

8

9

_this.get(

   this.url_s+"/Notice/findTotalCount",{

    userId:localStorage.getItem("userid"),

    openId: localStorage.getItem(‘openId‘)

   }

  )

  .then(function(res) {

   //

  })

原文地址:https://www.cnblogs.com/hudayang2008/p/9813342.html

时间: 2024-11-15 00:32:55

axios对请求各种异常情况处理的封装方法的相关文章

VUE.JS 使用axios数据请求时数据绑定时 报错 TypeError: Cannot set property 'xxxx' of undefined 的解决办法

正常情况下在data里面都有做了定义 在函数里面进行赋值 这时候你运行时会发现,数据可以请求到,但是会报错 TypeError: Cannot set property 'listgroup' of undefined 主要原因是: 在 then的内部不能使用Vue的实例化的this, 因为在内部 this 没有被绑定.可以看下 Stackoverflow 的解释: 解决办法: 1.用ES6箭头函数,箭头方法可以和父方法共享变量 2.在请求axios外面定义一下 var that=this 问题

axios网络请求

axios网络请求 淘汰ajax,jquery ajax,选择axios axios名称的由来? 个人理解 axios: ajax i/o system 请求方式 axios(config) //默认请求方式 axios.request(config) axios.get(url,{config}) axios.delete(url,{config}) axios.head(url,{config}) axios.post(url,data,{config}) axios.put(url,dat

记录一次追查server死机& 登录异常情况

linux 服务器死机了,于是追查原因. 查看boot.log [email protected]:/var/log$ less boot.log 看不出异常 显示开机信息 [email protected]:/var/log$ less dmesg 区别;(未明) /var/log/boot.log --- System boot log /var/log/dmesg --- print or control the kernel ring buffer /var/log/messages看看

Activity在异常情况下的生命周期——Android开发艺术探索笔记

欢迎转载,转载请注明出处 http://blog.csdn.net/l664675249/article/details/50638398 Activity在异常情况下的生命周期 关于Activity正常情况下的生命周期请参考这篇文章,本文主要讲解Activity在异常情况下的生命周期. 情况1:资源相关的系统配置发生改变 资源相关的系统配置发生改变,举个栗子.当前Activity处于竖屏状态的时候突然转成横屏,系统配置发生了改变,Activity就会销毁并且重建,其onPause, onSto

更加强健的线程模型,解决线程卡死,退出异常情况

线程模型 1 package net.sz; 2 3 import java.util.Random; 4 import java.util.concurrent.ConcurrentLinkedQueue; 5 import org.apache.log4j.Logger; 6 7 /** 8 * 9 * <br> 10 * author 失足程序员<br> 11 * mail [email protected]<br> 12 * phone 13882122019&

spring autowired时发生异常情况

spring beanFactory那些就不说了,这次发生这个异常纠结好了好久,网上找了很多资料看,终于发现问题. 自动装配bean注入的时候,如果Spring配置定义了aop声明式事务,类似如下方式 <aop:config>  <aop:pointcut id="serviceMethods2"   expression="execution(public * net.villion.framework..*(..))" />  <a

异常情况下的Activity生命周期分析

情况1:资源相关的系统配置发生改变 资源相关的系统配置发生改变,举个栗子.当前Activity处于竖屏状态的时候突然转成横屏,系统配置发生了改变,Activity就会销毁并且重建,其onPause, onStop, onDestory均会被调用.因为实在异常情况下终止的,所以系统会调用onSaveInstanceState来保存当前Activity状态.这个方法是在onStop之前,与onPause没有固定的时序关系.当Activity重建的时候系统会把onSaveInstanceState所保

Vuex + axios 发送请求

Vue 原本有一个官方推荐的 ajax 插件 vue-resource,但是自从 Vue 更新到 2.0 之后,官方就不再更新 vue-resource 目前主流的 Vue 项目,都选择 axios 来完成 ajax 请求,而大型项目都会使用 Vuex 来管理数据,所以这篇博客将结合两者来发送请求 前言: Vuex 的安装将不再赘述,可以参考之前的博客 Vue 爬坑之路(四)-- 与 Vuex 的第一次接触 使用 cnpm 安装 axios cnpm install axios -S 安装其他插

python3 selenium 如何处理异常情况

使用场景: 1.元素只有在某一特定情况下才会出现 2.元素定位不到 使用方法: try: except exceptions.NoSuchElementException: 举例说明: 1 # _._ coding=utf-8 _._ 2 """ 3 :author: 花花测试 4 :time: 2017.05.08 5 :content: 处理元素定位的异常情况 6 """ 7 8 from selenium import webdriver