淘先锋技术网

首页 1 2 3 4 5 6 7

Vue axios基础

基于 promise 的 HTTP 客户端axios
axios本身具有以下特征:
  • 从浏览器中创建 XMLHttpRequest
  • 从 node.js 发出 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防止 CSRF/XSRF

Promise

Promise 是异步编程的一种解决方案,而且还是以一种优雅的方式来处理异步请求的,本质上是一个构造函数,函数本身上巨有all、reject、resolve这几个方法,原型上有then、catch等方法。
对于主要解决的问题,由于笔者至今还未遇到过这样的需求,所以感触并没有太深刻,但是可以简单说明一下:
比如说对于传统的Ajax请求,如果第一次通过url1发送请求的时候需要服务器返回一个数据data1,而我们又需要data1取出url2的地址,来进行第二次网络请求,同理,第三次网络请求又需要第二次网络请求的返回的数据data2取出的url3… 这样一层层下去,不仅仅需要先验判断某一层网络请求失败的情况的代码,而且我们不能很好地将数据处理和数据请求分离,这样的代码就会显得很是冗余,一旦出现bug,对开发人员的debug要求就会变得很高。

其大致用法如下:

// 第一次异步网络请求
new Promise((resolve,reject) => {
	// 异步通信数据请求代码
	resolve(val) // 请求成功调用此函数
	reject(err) // 请求失败调用此函数
}).then(val => {
	// 处理第一次成功请求
	// 第二次异步网络请求
	new Promise((resolve,reject) => {
		// 异步通信数据请求代码
		resolve(val) // 请求成功调用此函数
		reject(err) // 请求失败调用此函数
	}).then(val => {
		...
	}).catch(err => {
		...
	})
}).catch(err => {
	// 处理第一次失败请求
})

axios的基本使用

项目根目录下执行以下命令安装axios:

npm install axios --save

导入并使用axios:

import axios from 'axios'

// get方式
axios({
  url: "http://httpbin.org/get",
  method: 'get',
  params:{
    name: "张三",
    id: 1001,
    age: 21
  }
}).then(res => {
  console.log(res);
})
// post方式
axios({
  url: "http://httpbin.org/post",
  method: 'post',
  data:{
    name: "张三",
    id: 1000,
    age: 20
  }
}).then(res => {
  console.log(res);
})

结果显示:

在这里插入图片描述

axios的并发请求

有时候,我们需要满足这样的需求:必须在特定的一些网络请求全部成功后才能统一执行某一事件。而axios已经封装好了这个方法,如下演示:

import axios from 'axios'


axios.all([
    axios({
      method: "get",
      url: "http://httpbin.org/get",
      params:{
        name:"张三",
        id: 1001
      }
    }).then(res => {
      console.log("第一个axios请求成功",res);
      return res;
    }),
    axios({
      method: "post",
      url: "http://httpbin.org/post",
      data: {
        name:"李四",
        id: 1002
      }
    }).then(res => {
      console.log("第二个axios请求成功",res);
      return res;
    }),
    axios({
      method: "post",
      url: "http://httpbin.org/post",
      data: {
        name:"王五",
        id: 1003
      }
    }).then(res => {
      console.log("第三个axios请求成功",res);
      return res;
    })
]).then(result => {
  console.log("这个一定是等待以上全部请求成功后… ",result[0],result[1],result[2]);
})

在这里插入图片描述

为了减少相关代码的重复冗余,选择公共默认选项,可以使用axios.defaults方法,如下演示:

axios.defaults.baseURL = "http://httpbin.org"; 
axios.defaults.timeout = 1000; // 超时限制
axios({
  url: "/get",
  method: 'get',
  params:{
    name: "张三",
    id: 1001,
    age: 21
  }
}).then(res => {
  console.log(res);
})

axios({
  url: "/post",
  method: 'post',
  data:{
    name: "张三",
    id: 1000,
    age: 20
  }
}).then(res => {
  console.log(res);
})

axios实例化

对于一些分布式服务器来说,全局配置axios可能是会冲突的,因此,axios允许创建axios实例。
const request1 = axios.create({
  baseURL: "http://httpbin.org",
  timeout: 1000
})
const request2 = axios.create({
  baseURL:"http://httpbin.org",
  timeout: 2000,
  method: "post"
})
request1({
  url: "/get",
  params:{
    name:"张三",
    age: 20
  }
}).then(res => {
  console.log(res);
})
request2({
  url: "/post",
  data:{
    name:"李四",
    age: 21
  }
}).then(res => {
  console.log(res);
})

在这里插入图片描述

axios模块化

为了减少网页之间与axios之间的耦合度(解耦合),可以通过一个文件作为全局索引导入。

如,可以在src目录下创建一个network文件夹,目录下再创建request.js:

import axios from  'axios'

// 这里config作为配置参数,success作为成功回调函数,failure作为失败回调函数
export function request(config,success,failure){
  const instance = axios.create({
    baseURL: "http://httpbin.org",
    timeout: 2000
  })
  // 发送真正的网络请求
  instance(config).then(res => {
      success(res)
    }).catch(err => {
      failure(err)
  })
}

使用方式:


import {request} from './network/request'

request({
  url: "get",
  method: 'get',
  params: {
    name: "张三",
    age: 20
  }
}, res => {
  console.log(res);
}, err => {
  console.log(err);
})

request({
  url: "post",
  method: 'post',
  data: {
    name: "王五",
    age: 21
  }
}, res => {
  console.log(res);
}, err => {
  console.log(err);
})

在这里插入图片描述

上例解释,创建一个axios实例,实现多组件共享,通过传递成功请求回调函数和传递失败回调函数作为一个出口,用户通过传递config参数也能自定义配置。同样,读者也可以实现多个axios默认实例导出供多个组件共享。

以上版本可以进一步升级,通过Promise方式,即进一步封装增强Promise:

request.js:

export function request(config){
  return new Promise((resolve,reject) => {
    // 配置默认项
    const instance = axios.create({
      baseURL: "http://httpbin.org",
      timeout: 2000
    })
    // 发送网络请求
    instance(config)
        .then(res => {
          resolve(res)
        })
        .catch(err => {
          reject(err)
        })
  })
}

使用方式:

import {request} from './network/request'

request({
  url: "/get",
  method: 'get',
  params:{
    name: "张三",
    age: 20
  }
}).then(res => {
  console.log(res);
}).catch(err => {
  console.log(err);
})

request({
  url: "/post",
  method: 'post',
  params:{
    name: "赵六",
    age: 21
  }
}).then(res => {
  console.log(res);
}).catch(err => {
  console.log(err);
})

再进一步升级简化:

export function request(config){
  const instance = axios.create({
    baseURL: "http://httpbin.org",
    timeout: 2000
  })
  // 发送真正的网络请求
  return instance(config);
}

之所以可以像上面一样可以直接返回axios实例,是因为其本身就是继承了Promise。

拦截器

对于请求成功或失败,相应成功或失败都可以进行相应拦截操作。

一般可用作网络加载页面图标显示,或者登录页面的token验证等…

request.js:

export function request(config){
  const instance = axios.create({
    baseURL: "http://httpbin.org",
    timeout: 2000
  })
  instance.interceptors.request.use(config => {
    console.log("请求拦截配置:",config);
    return config;
  },err => {
    console.log(err);
  })
  instance.interceptors.response.use(res => {
    console.log("响应拦截结果:",res);
    return res.data.args; // 返回data即可
  },err => {
    console.log(err);
  })
  // 发送真正的网络请求
  return instance(config);
}

使用:


import {request} from './network/request'

request({
  url: "/get",
  method: 'get',
  params:{
    name: "张三",
    age: 20
  }
}).then(res => {
  console.log(res);
}).catch(err => {
  console.log(err);
})

在这里插入图片描述