zoukankan      html  css  js  c++  java
  • 网络模块axios的简单应用

    一、axios的基本使用

    例子中使用到的url仅作为示例,不一定有效,想要复现代码需要使用能够提供数据的有效服务器接口url

    1.1.什么是axios

    axios:ajax i/o system;是用于在Vue.js中发送网络请求的第三方框架;

    可通过许多方式发送网络请求比如:

    • 选择一:传统的Ajax,配置和调用方式十分混乱,不推荐;
    • 选择二:jQuery-Ajax,基于jQuery框架,不适合在Vue.js中使用;
    • 选择三:官方在Vue1.x时推出的Vue-resource,由于官方不再维护,不推荐;
    • 最佳选择:Vue.js作者尤雨溪推荐的axios,具有非常多的优点,使用起来也十分方便。

    1.2.安装axios

    想要使用axios首先要在node中安装axios,由于运行时依赖axios,所以采用‘--save’的安装方式。

    npm install axios --save
    

    1.3.axios的基本使用

    //首先要引入
    import axios from 'axios'
    
    //1.最基本的使用方式,method表示请求数据的方法,res为请求到的数据,可在then()中处理。(url仅为示例,表示的服务器接口并不一定存在)
    axios({
      url: 'http://123.207.32.32:8000/home/multidata',
      method: 'get'
    }).then(res => {
      console.log(res); 
    })
    
    //2.进行参数拼接
    axios({
      url: 'http://123.207.32.32:8000/home/data',
      // 专门针对get请求的参数拼接
      params: {
        type: 'pop',
        page: 1
      }
    }).then(res => {
      console.log(res);
      
    }) 
    
    

    1.4.axios发送并发请求

    以下为使用全局的axios和对应的配置进行网络请求,其中的url都要拼接上baseURL。这种方式只能向固定的服务器接口地址'http://123.207.32.32:8000' 请求数据,不能满足向不同的分布式服务器请求数据的需求。

    //定义全局的baseURL和请求时间timeout
    axios.defaults.baseURL = 'http://123.207.32.32:8000'
    axios.defaults.timeout = 5000
    
    //使用axios.all()进行并发的数据请求,同样使用then()处理请求到的数据
    axios.all([axios({
      url: '/home/multidata'
    }), axios({
      url: '/home/data',
      params: {
        type: 'sell',
        page: 5
      }
    })])
    .then(axios.spread((res1, res2) => {
      console.log(res1);
      console.log(res2);
    }))
    
    
    

    1.5.创建axios实例请求数据

    通过创建axios实例,每一个被创建的实例都有各自的配置,可以向不同ip地址的服务器请求数据,彼此互不干扰。

    //创建第一个axios实例:instance1
    const instance1 =  axios.create({
      baseURL: 'http://123.207.32.32:8000',
      timeout: 5000
    })
    
    //实例instance1可单独的向服务器请求数据并进行处理
    instance1({
      url: '/home/multidata'
    }).then(res => {
      console.log(res);
    })
    
    //也可以采用拼接参数的方式请求数据,实例instance1拥有自己的配置
    instance1({
      url: '/home/data',
      params: {
        type: 'pop',
        page: 1
      }
    }).then(res => {
      console.log(res);
    })
    
    // 如果有其他请求可以再创建一个axios的实例:instance2,这样就可以向其他ip地址的服务器接口请求数据了
    const instance2 = axios.create({
      baseURL: 'http://222.111.33.33:8000',
      timeout: 10000,
      // headers: { }//还可以根据需要配置对应的headers
    })
    
    

    二、axios的应用

    2.1.不规范的写法

    在组件App.vue中按如下方式请求数据,并进行展示:

    <template>
      <div id="app">
        <!-- 打印请求到的数据 -->
        <div>{{result}}</div>
      </div>
    </template>
    
    <script>
    // 引入axios
    import axios from 'axios'
    
    export default {
      name: 'App',
      components: {
    
      },
      data(){
        return {
          // 对请求来的数据进行处理(这里省略)
          result:''
        }
      },
      //生命周期函数created():在Vue实例创建的时候就调用。在这里实现,Vue实例一创建便发送数据请求
      created(){
        axios({
          url: 'http://123.207.32.32.:8000/api/home/multidate'
        }).then(res => {
          console.log(res);
          // 将请求到的数据res存储到data中
          this.result = res;
        })
      }
    }
    </script>
    
    <style>
    
    </style>
    
    

    虽然这种方法也可以正常请求到数据,但是,如果每一个组件都使用这种方式请求数据,就会对第三方框架axios产生过度的依赖。一旦axios框架不再维护或出现重大bug不再修复,想要在原有项目中去除对第三方框架axios的依赖使用其他框架就会变得十分复杂。所以这种请求数据的方式虽可行,但是非常不规范。不符合"高内聚,低耦合"的程序设计思想。

    2.2.axios的规范用法

    单独封装一个axios组件进行数据请求(模块化思想)。如图,这样即使第三方框架axios更改了,只需要修改封装的组件x即可。所以,当我们使用第三方框架的时候,最好采用这种方式,减小对第三方框架的依赖,便于维护。

    image-20200225121018327

    首先在,项目目录的src(源码)文件夹下新建network文件夹,再在里面新建request.js文件,专门用于放置axios数据请求组件:

    image-20200225131402281

    以下示例为,在request.js文件中封装axios数据请求模块,在main.js中进行数据请求。

    方式一:

    在request.js中:

    //导入第三方框架
    import axios from 'axios'
    
    //1.创建axios的实例(不要使用全局的方式)并进行相应配置
    /* 
    为了考虑扩展性,不要用export default 直接导出axios对象。而是一函数形式导出,函数里面可有多个axios实例
    传入三个参数:其中success和failure分别是表示请求成功和失败后的处理函数,负责把请求到的数据通过回调传出去
    */
    export function request(config, success, failure) {
    //该函数的基本配置
      const instance = axios.create({
        baseURL: 'http://123.207.32.32:8000',
        timeout: 5000
      })
    
      //2.发送真正的网络请求(在该函数的相同配置下可创建不同的实例);
      /*
      这里axios实例instance的参数config是在request函数基本配置基础上的配置:传入config中的url: '/home',那么加上request函数的基本配置,最后请求数据的url:'http://123.207.32.32:8000/home';相当于request函数确定请求的服务器地址,request函数里的axios实例请求同一服务器上的其他接口(分页)数据。
      */
      instance(config)
      .then(res => {
        // 通过回调传入的success函数的方式把请求到的数据传出去
        success(res)
      })
      .catch(err => {
        // 同上
        failure(err)
      })
    }
    
    /* 可传出包含多个实例的多个函数
    export function instance2() {
    
    } 
    

    在main.js文件中请求数据:

    //导入第三方框架
    import axios from 'axios'
    
    // 引入request函数.
    import { request } from "./network/request";
    //调用request函数,传入三个参数
    request(
      // 参数1:config
      {
      url: '/home/multidata'
      }, 
      // 参数2:success函数
      /* 
        补充:如何实现回调?
        1.把success函数当作参数传入request函数;
        2.request函数调用传进来的success函数,并传入请求到的数据:success(res);
        3.success(res)相当于函数调用,回到了这里调用success函数,并成功地把res传了过来.
      */
      res => {
        console.log(res);//处理代码
    },
      // 参数3:failure函数
      err => {
        console.log(err);
      } 
    )
    

    方式二:

    只给request函数传入一个参数config:

    在request.js中:

    // 导入axios框架
    import axios from 'axios'
    
    //要求传入的config中包含success和failure两个函数
    export function request(config) {
      const instance = axios.create({
        baseURL: 'http://123.207.32.32:8000',
        timeout: 5000
      })
    
      //2.发送真正的网络请求,config.baseConfig负责传入各axios实例的配置
      instance(config.baseConfig)
      .then(res => {
        // 通过config调用success函数
        config.success(res)
      })
      .catch(err => {
        config.failure(err)
      })
    }
    
    

    在main.js文件中请求数据:

    // 引入request函数.
    import { request } from "./network/request";
    
    //仅传入一个参数:config对象
    request ({
      baseConfig: {
        // 基本配置
      },
      success: function(res){
    	//处理代码
      },
      failure: function (err){
        //处理代码
      }
    })
    

    方式三(更优雅):

    上面的两种方式都是采用回调函数的方式,不够优雅。更加优雅的方式是采用ES6的Promise实现:

    在request.js中:

    // 导入axios框架
    import axios from 'axios'
    
    export function request(config) {
      //在函数中返回一个新建的Promise对象
      return new Promise((resolve, reject) => {
        //1.发送真正的网络请求
        const instance = axios.create({
          baseURL: 'http://123.207.32.32:8000',
          timeout: 5000
        })
      
      //2.发送真正的网络请求,config.baseConfig负责传入基本配置
      instance(config)
      .then(res => {
      //通过Promise对象的resolve和reject函数把请求到的数据传出去
        resolve(res)
      })
      .catch(err => {
        reject(err)
      })
    
      })
    }
    
    

    在main.js文件中请求数据:

    // 引入request函数.
    import { request } from "./network/request";
    
    //注意request函数返回了一个Promise对象,所以可以直接.then()进行处理
    request({
      url: '/home/multidata',
    }).then(res => {
      console.log(res)
    }).catch(err => {
      console.log(err)
    })
    

    方式四(最优雅):

    以为就只有上面三种封装方法?还有对优雅的封装方式呢:

    在request.js中:

    export function request(config) {
        //1.创建axios实例
        const instance = axios.create({
          baseURL: 'http://123.207.32.32:8000',
          timeout: 5000
        })
    
        //2.发送真正的网络请求
        // 实际上instance(config)返回的即是一个Promise,不必像方式三一样在函数中封装一层Promise并返回出去
        return instance(config)
    }
    
    

    在main.js文件中请求数据:

    // 引入request函数.
    import { request } from "./network/request";
    
    request({
      url: '/home/multidata',
    }).then(res => {
      console.log(res)
    }).catch(err => {
      console.log(err)
    })
    
    

    总结:封装的方式推荐使用方式四,最灵活也最简洁。封装完毕之后,想要发送网络请求只需要引入并调用request()函数就行了。这样,即使axios框架不维护了,也只是需要更改request()函数而已,十分利于维护。


    三、axios拦截器

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

    拦截器一共提供了四种拦截:

    • 请求成功后拦截
    • 请求失败后拦截
    • 响应成功后拦截
    • 响应失败后拦截

    在上面封装好的request.js基础上添加拦截器:

    export function request(config) {
        //1.创建axios实例
        const instance = axios.create({
          baseURL: 'http://123.207.32.32:8000',
          timeout: 5000,
         // headers:{}
        })
    	
        /* 
        2.axios拦截器
        axios.interceptors:全局拦截器
        局部拦截器(仅拦截instance实例)
        use()的两个参数都为函数
        */
        /*
        2.1.请求拦截:
        成功发出请求时,使用use()第一个参数(函数)处理;
        发出请求失败时,使用use()第而个参数(函数)处理
        */
    	 instance.interceptors.request.use(
    	 //拦截到的时config配置信息
    	 config => {
          console.log(config);//打印拦截信息
          
          /*
          这里可以对拦截到的信息进行处理
          */
          //拦截完config之后一定要返回,不然请求就发不出去了
          return config;
        },
        err => {
          console.log(err);
        }
        );
        
        /*
        2.2.响应拦截:
        响应成功,使用use()第一个参数(函数)处理;
        响应失败,使用use()第而个参数(函数)处理
        */
         instance.interceptors.response.use(
         //拦截到的是服务器返回的数据res
         res => {
    		console.log(res);
    		// 同样处理完后一定要返回被拦截的结果res,这里只返回res.data即可,因为服务器的响应一般是数据
    		return res.data;
        },
         err => {
          console.log(err);
        }
        )
        
        //3.发送真正的网络请求
        return instance(config)
    }
    

    在main.js中调用request函数发送网络请求:

    // 引入request函数.
    import { request } from "./network/request";
    
    request({
      url: '/home/multidata',
    }).then(res => {
      console.log(res)
    }).catch(err => {
      console.log(err)
    })
    

    请求拦截:

    image-20200225150713098

    image-20200225150640465

    可以看到当成功发出请求时,在request.js中的第88行打印了请求拦截的信息就是出传入的config相关配置。当发送请求失败时,由use()的第二个参数(函数)打印失败信息。

    响应拦截:

    image-20200225154655619

    image-20200225154757043

    当服务器响应失败时,由use()的第二个参数(函数)打印失败信息。

    为什么需要请求拦截?/请求拦截的作用

    • 当config中的一些信息不符合服务器的要求时。比如修改headers信息,除了可以在创建axios实例时修改时,还可以拦截之后进行修改。

    • 当每次发送网络请求时,都希望在界面中显示一个请求的图标。就可以在拦截后通过show()显示出来,请求成功后,再在相应拦截中进行隐藏。

    • 某些网络请求(比如登录(token)),必须携带一些特殊的信息。

  • 相关阅读:
    MyEclipse控制台输出tomcat红字
    struts标签bean:define
    字节流转换为对象的方法
    C#将jpg格式图片合成到bmp格式图片中
    [置顶]C#中Socket服务端代码分享
    [置顶] C#中Socket服务端代码分享
    [置顶] 使用Joson的格式字符串在Socket中通讯时数据格式的转换
    [置顶] AMF序列化为对象和AMF序列化为二进制字节流
    用C#获取CPU编号、硬盘编号等系统有关环境、属性
    别把紧张情绪带回家 下班后的10个最佳放松法
  • 原文地址:https://www.cnblogs.com/AhuntSun-blog/p/12362257.html
Copyright © 2011-2022 走看看