网络模块封装axios

模块的选择

Vue中发送网络请求有非常多的方式, 那么, 在开发中, 如何选择呢?

  1. 传统的Ajax是基于XMLHttpRequest(XHR)
  2. 使用jQuery-Ajax
  3. 官方在Vue1.x的时候, 推出了Vue-resource
  4. axios

比较差异: 传统的Ajax配置和调用方式等非常混乱.编码起来看起来就非常蛋疼.所以真实开发中很少直接使用, 而jQuery-Ajax,在Vue的整个开发中都是不需要使用jQuery了.为了方便我们进行一个网络请求, 特意引用一个jQuery,

你觉得合理吗?完全没有必要为了用网络请求就引用这个重量级的框架.Vue作者就在GitHub的Issues中说明了去掉vue-resource, 并且以后也不会再更新.那么意味着以后vue-reource不再支持新的版本时, 也不会再继续更新和维护.
对以后的项目开发和维护都存在很大的隐患.

综上,我们使用axios作为发送网络请求的模块

认识axios

基于promise用于浏览器和node.js的http客户端

功能特点:

  • 支持浏览器和node.js
  • 支持promise
  • 能拦截请求和响应
  • 能转换请求和响应数据
  • 自动转换JSON数据
  • 浏览器端支持防止CSRF(跨站请求伪造)

发送基本请求

HttpBin 介绍

httpbin是一个HTTP Request & Response Service,你可以向他发送请求,然后他会按照指定的规则将你的请求返回。这个类似于echo服务器,但是功能又比它要更强大一些。 httpbin支持HTTP/HTTPS,支持所有的HTTP动词,能模拟302跳转乃至302跳转的次数,还可以返回一个HTML文件或一个XML文件或一个图片文件(还支持指定返回图片的格式)。实在是请求调试中居家必备的良器!

httpbin怎么用

httpbin的使用方法非常简单,你只需要把请求的地址修改为httpbin.org即可。 比如:

curl http://httpbin.org/user-agent

查看自己的GET请求

curl http://httpbin.org/get

Get request

#Get request
//没有请求参数
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

Post request

#Post request 
//有请求参数
axios.post('/save', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

发送并发请求

有时候, 我们可能需求同时发送两个请求.使用axios.all, 可以放入多个请求的数组.axios.all([]) 返回的结果是一个数组,使用 axios.spread 可将数组 [res1,res2] 展开为 res1, res2

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread((acct, perms)=>{
      console.info(acct);  
      console.info(perms);  
 }));

可用的api别名

axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
#注:当使用以上别名方法时,url,method和data等属性不用在config重复声明。

#全局配置

在上面的示例中, 我们的BaseURL是固定的.事实上, 在开发中可能很多参数都是固定的.这个时候我们可以进行一些抽取, 也可以利用axiox的全局配置

//提取全局配置
axios.defaults.baseURL = ‘http://123.207.32.32:8000’
axios.defaults.headers.post[‘Content-Type’] = ‘application/x-www-form-urlencoded’;

//发送并发请求
axios.all([
	axios.get('/user/12345'), 
	axios.get('/user/12345/permissions')])
  .then(axios.spread((acct, perms)=>{
      console.info(acct);  
      console.info(perms);  
 }));

常见的配置选项

请求地址url: ‘/user’
请求类型method: ‘get’,
请根路径baseURL: ‘http://www.mt.com/api’,
请求前的数据处理transformRequest:[function(data){}],
请求后的数据处理transformResponse: [function(data){}],
自定义的请求头headers:{‘x-Requested-With’:‘XMLHttpRequest’},
URL查询对象params:{ id: 12 },
查询对象序列化函数paramsSerializer: function(params){ }
request bodydata: { key: ‘aa’},
超时设置stimeout: 1000,
跨域是否带TokenwithCredentials: false,
自定义请求处理adapter: function(resolve, reject, config){},
身份验证信息auth: { uname: ‘’, pwd: ‘12’},
响应的数据格式 json / blob /document /arraybuffer / text / streamresponseType: ‘json’,

axios实例

为什么要创建axios的实例呢?

当我们从axios模块中导入对象时, 使用的实例是默认的实例.当给该实例设置一些默认配置时, 这些配置就被固定下来了.但是后续开发中, 某些配置可能会不太一样.比如某些请求需要使用特定的baseURL或者timeout或者content-Type等.这个时候, 我们就可以创建新的实例, 并且传入属于该实例的配置信息.

拦截器

axios提供了拦截器,用于我们在发送每次请求或者得到相应后,进行对应的处理。

拦截器语法

// 添加一个请求拦截器
axios.interceptors.request.use(function (response) {
    console.info("来到了request拦截的success中")
    return response;
  }, function (error) {
     console.info("来到了request拦截的error中")
    return error;
  });

// 添加一个响应的拦截器
axios.interceptors.response.use(function (response) {
    console.info("来到了response拦截的success中")
    return response.data;
  }, function (error) {
   console.info("来到了response拦截的error中")
    return error;
  });

拦截器中都做什么呢?

请求拦截可以做到的事情:

  1. 当发送网络请求时,在页面中添加一个loading组件,作为动画
  2. 某些请求要求用户必须登入,判断用户是否有token,如果没有token跳到login页面
  3. 对请求参数进行序列化

添加响应拦截器,统一处理服务器响应和异常

 /**
       * 添加响应拦截器,统一处理服务器响应和异常
       */
      axios.interceptors.response.use(
        response => {
          return response
        },
        error => {
          /**
           * 状态码401代表无权限访问,权限失效,需要重新获取authToken
           * 状态码500代表REST服务器异常
           */
          const status = error.response.status
          const message = error.response.data.meta.message
          if (status === 401) {
            /**
             * 登录授权token超时,提示
             */
            if (message.indexOf('ERROR_CODE_001') > -1) {
              this.$message.error(errorCode.ERROR_CODE_001)
            }

            window.location.href = `${window.location.origin}/login`
            return Promise.reject(error)
          }

          /**
           * 1.处理系统服务异常
           * 2.处理SoaException异常
           */
          if (status === 500) {
            if (message.indexOf('ERROR_CODE_003') > -1) {
              this.$message.error(errorCode.ERROR_CODE_003)
              return
            }

            this.$message.error(message)
          }

          return Promise.reject(error)
        }
      )

封装axios api http.js,便捷方法调用

/**
* http.js
* 封装axios,
* 调用方法:
* http.get('/api/enquiry/web/query',{id:1}).then((res)=>{你的操作})
* http.post('/api/enquiry/web/update',{id:1}).then((res)=>{你的操作})
* http.postFormData('/api/enquiry/web/update',{id:1,file:file}).then((res)=>{你的操作})
*/
import axios from 'axios'

export default {
 /**
  * get方法,对应get请求
  * @param {String} url [请求的url地址]
  * @param {Object} params [请求时携带的参数]
  */
 get (url, params) {
   return new Promise((resolve, reject) => {
     axios.get(url, {
       params: params
     }).then(res => {
       resolve(res.data)
     }).catch(err => {
       reject(err)
     })
   })
 },
 /**
  * post方法,对应post请求
  * @param {String} url [请求的url地址]
  * @param {Object} params [请求时携带的参数]
  */
 post (url, params) {
   return new Promise((resolve, reject) => {
     axios.post(url, params)
       .then(res => {
         resolve(res.data)
       })
       .catch(err => {
         reject(err)
       })
   })
 },
 /**
  * postFormData方法,对应post请求,用来提交文件+数据
  * @param {String} url [请求的url地址]
  * @param {Object} params [请求时携带的参数]
  */
 postFormData (url, params) {
   return new Promise((resolve, reject) => {
     axios({
       headers: {
         'Content-Type': 'multipart/form-data'// ;boundary=----WebKitFormBoundaryQ6d2Qh69dv9wad2u
       },
       transformRequest: [function (data) { // 在请求之前对data传参进行格式转换
         const formData = new FormData()
         Object.keys(data).forEach(key => {
           formData.append(key, data[key])
         })
         return formData
       }],
       url,
       method: 'post',
       data: params
     }).then(res => {
       resolve(res.data)
     }).catch(err => {
       reject(err)
     })
   })
 }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李熠漾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值