浅谈vue项目进阶开发-axios篇

今天来谈一谈有关vue项目中使用Ajax插件库axios,以及对它做的一些封装。

安装就不再提了,在这axios

1.简单使用

axios.post('/user' , {
  params: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
}).then(function (response) {
    console.log(response);
  }).catch(function (error) {
    console.log(error);
  });

无需多言,一目了然。

 对于接口地址我们需要处理一下跨域问题:

  使用http-proxy-middleware 代理解决:

例如请求的url:“http://f.apiplus.cn/bj11x5.json

a、打开config/index.js,在proxyTable中添写如下代码:

proxyTable: { 
  '/api': {  //使用"/api"来代替"http://f.apiplus.c" 
    target: 'http://f.apiplus.cn', //源地址 
    changeOrigin: true, //改变源 
    pathRewrite: { 
      '^/api': 'http://f.apiplus.cn' //路径重写 
      } 
  } 
}

b.使用时 

getData () { 
 axios.get('/api/bj11x5.json', function (res) { 
   console.log(res) 
 })

c.通过这中方法去解决跨域,打包部署时还按这种方法会出问题。解决方法如下:

let serverUrl = '/api/'  //本地调试时 
// let serverUrl = 'http://f.apiplus.cn/'  //打包部署上线时 
export default { 
  dataUrl: serverUrl + 'bj11x5.json' 
}

 但是这种解决方法处理时,当线上的域名与接口不一致时会出现同一个请求发送两次的问题。网上说的解决方式是在请求头部加上Access-Control-Max-Age(单位s),这个是预检请求的时间,只要设置的时间足够长就能解决该问题,(Chrome时间上限为600s),然而亲测无效。大家可以试试。

2.axios拦截器

axios拦截器有两种,请求拦截和响应拦截,其目的是为了在接口请求和响应时统一地处理一些事情,比如网络错误,后端抛出的错误。

import axios from 'axios'

// 添加一个请求拦截器
axios.interceptors.request.use(config => {
  // Do something before request is sent
  return config
}, error => {
  // Do something with request error
  return Promise.reject(error)
});

// 添加一个响应拦截器
axios.interceptors.response.use(response => {
  // Do something with response data
  return response
}, error => {
  // Do something with response error
  return Promise.resolve(error.response)
});

在这里我们并没有在拦截器里面处理我们需要处理的事情,当然你可以这么做。我们用promise链式处理接口异常。

3.封装

处理方式如下:

  request(obj) {
    return new Promise((resolve, reject) => {
      axios({
        method: obj.method,
        baseURL: obj.baseUrl,
        url: obj.path,
        data: obj.method === 'post' ? obj.params : {},
        params: obj.method === 'get' ? obj.params : {},
        timeout: 20000,
        withCredentials: true,
        headers: {
          'X-Requested-With': 'XMLHttpRequest',
          'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
        }
      }).then((res) => {
        return _checkStatus(res)
      }).then((res) => {
        if (res.retCode !== 0) {
          if (obj.showErr) {
             // 如果retCode异常(这里包括后端抛出的错误),可以弹出一个错误提示,告诉用户
             Message({showClose: true, message: res.retMsg, type: 'warning'});
          } else {
            return reject(res)
          }
        } else {
          return resolve(res)
        }
      }).catch((err) => {
        return reject({retMsg: '未知错误', retCode: 500})
      })
    })
  }

这里处理接口异常情况主要有两种,第一种是code码异常也就是code为非200状态,第二种是接口返回数据异常(retCode异常)。第一种情况我们用_checkStatus()处理的,具体如下:

function _checkStatus(response) {
  // loading
  // 如果http状态码正常,则直接返回数据
  if (response && (response.status === 200 || response.status === 304 || response.status === 400)) {
    return response;
  }
  // 异常状态下,把错误信息返回去
  return {
    status: -404,
    msg: '网络异常'
  }
}

第二种情况 我们这么处理的:

        if (res.retCode !== 0) {
          if (obj.showErr) {
            _dealCode(res);
          } else {
            return reject(res)
          }
        } else {
          return resolve(res)
        }

解释下,这里的showErr是控制是否统一处理错误,有时候我们需要单独去处理一些特殊情况的错误反馈。这里的res.retcode!==0表示http状态码正确(接口连接正常),但返回的数据有问题,不同的retCode代表不同的意思,这个可以跟后端约定好,后端会把数据异常原因放在retMsg里面,比如和后端约定好retCode===999时,表示传参出错,retMsg = ‘传参错误’。

正常情况下我们直接统一弹出一个错误提示给用户就好了,但有时候需要特殊处理此时chua传参数时showErr=false即可.

调用时这么做即可:

 this.$http.request({'https://baishsd.com/', path: 'newCost/Report/ChartAcpe', params, method:'post',showErr:true}).then(res => {})

 使用时加上showErr,无需catch捕获异常,已统一处理。

不过这么写参数还是麻烦了一点,可以自己封装下参数,全部写在app.js中统一放置接口,统一管理

猜你喜欢

转载自blog.csdn.net/weixin_37693991/article/details/83111705