关于axios,你需要了解什么?

417 阅读5分钟

axios

开发进行网络请求,可以选择以下方式:

  • Ajax,基于XMLHttpRequest(XHR)

    配置和调用太混乱,编码太复杂

  • jQuery-Ajax

    虽然比传统的Ajax好用,但在Vue开发中没有必要因为使用Ajax而引入jQuery

  • Vue-resource

    仅在Vue1.x时使用,现在已不再维护

  • axios( 官方推荐!!! ):ajax i/o system

    • 能在浏览器中发送 XMLHttpRequests 请求
    • 支持在node.js中发送http请求
    • 支持 Promise API
    • 拦截请求和响应
    • 转换请求和响应数据

基本使用

# 安装
npm install axios --save

# 导入
import axios from 'axios'

# 基本使用
axios({
  url: 'https://httpbin.org/headers',
  method: 'get'
}).then(res => {
  console.log(res);
})

# [备注] httpbin.org 网站太慢 测试用 请求可能需要几秒后才能相应返回数据
# [注] 哪个页面需要使用 axios 就需要在此页面开头 improt 导入

参数拼接

axios({
  url: 'http://xxx.com/page?',
  params: {		//params是专门针对get请求的参数拼接属性 
    location: 'beijing',
    key: 'abcd'
  }
//拼接后相当于 http://xxx.com/page?location=beijing&key=abcd
}

多请求并发

  • Promise.all()
  • axios.all()
axios.all([axios(), axios()]).then(res => {console.log(res);})
// 返回2个数组形式展示的请求结果

// 若不想以数组形式展示 可以使用spread()方式将结果单独展示
axios.all([axios(), axios()]).then(axios.spread((res1, res2) => {
  console.log(res1);
  console.log(res2);
}))

全局配置

在实际开发中,有很多参数都是固定重复的,此时可以使用 defaults 设置全局请求配置对其进行抽取

// 每个请求里需要重复写的数据放在这里 (公共数据)
axios.defaults.baseURL = 'http://xxx.com',
axios.defaults.timeout = 5000;     // 超时时间

axios({
  url: '/page',		//抽取之后 url就无需加上网站域名
}

axios常用配置项

  • url:请求地址(必写)

  • method:请求方法,默认 get

  • baseURL:请求根目录域名(常用)

  • transformRequest:允许在请求发送到服务器前,对请求的数据做出一些改动,只适用于 put/post/patch

  • transformResponse:允许在数据传送到 then/catch 方法前,对数据进行改动

  • headers:设置请求头json类型,自定义请求头信息

  • params:专门针对get请求的参数拼接属性

  • data:作为一个请求体而需要被发送的数据,只适用于 put/post/patch,在浏览器上data只能是FormData/File/Blob格式

  • timeout:超时时间

  • withCredentials:表明了是否是跨域请求、默认 default

  • onUploadProgress:上传进度事件

  • onDownloadProgress:下载进度的事件

  • maxContentLength:相应内容的最大值

  • auth:身份信息验证

  • responseType:请求数据格式

axios实例

当一个大项目中,数据的并发量很大,请求的服务器不一定只有一个,这时就会使用分布式请求,利用反向代理,向不同的服务器请求数据,此时就需要使用 axios.create() 来创建 axios 实例。

const axiosInstance1 = axios.create({
  baseURL: 'http://xxx.com',
  timeout: 5000
})

axiosInstance1({
  url: '/page/aaadata'
}).then(res => {
  console.log(res);
})

axiosInstance1({
  url: '/page/bbbdata'
}).then(res => {
  console.log(res);
})


const axiosInstance2 = axios.create({
  baseURL: 'http://yyy.com',
  timeout: 10000
})

axiosInstance2({
  url: '/home'
}).then(res => {
  console.log(res);
})

// 创建了2个实例 并且请求于不用的服务器地址 在使用时互不干扰

以上代码写于main.js中,但真实开发中一般不做这样。且不推荐在每个vue页面中都使用 import axios from 'axios' 进行导入,因为太繁琐,且对第三方框架依赖性太强,若当某天此框架不太更新维护,就需要大量的修改项目里的导入依赖,且需要修改的源代码也会过多。

解决办法是将所有网络请求统一封装到 /network/require.js 文件中。

import axios from 'axios'		// 只需导入一次

// 创建多个axios实例 可以多次导入
// export function axiosInstance1(){}
// export function axiosInstance2(){}

export function request(config, success, failure){
// 1.创建axios实例
const instance = axios.create({
 baseURL: 'http://xxx.com',
 timeout: 5000
})

// 发送真正的网络请求 但一般回调函数不在这里处理 需要传递出去 所以就需要success和failure参数
	instance(config)
 .then(res => {
   success(res)
})
 .catch(err => {
   failure(err)
})
}

在main.js中使用

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

// 在此处理结果
request({
 url: '/page'
	}, res => {
 console.log(res);
}, err => {
 console.log(err);
})


但以上的方式还是过于分散,还需要进行更深的封装

export function request(config) {
return new Promise((resolve, reject) => {
  const instance = axios.create({
     baseURL: 'http://xxx.com',
     timeout: 5000
   })

 	instance(config)
   	.then(res => {
     	resolve(res)
 		})
   	.catch(err => {
     	reject(err)
 		})
	})
}

在axios源代码中,本身就已经调用了Promise,所有以上就无需再使用Promise进行封装,直接简化代码

export function request(config) {
  const instance = axios.create({
    baseURL: 'http://xxx.com',
    timeout: 5000
  })
  return instance(config)
}

在main.js中使用

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

// 在此处理结果
request({
  url: '/page'
}).then(res => {
  console.log(res);
}).catch(err => {
  console.log(err);
})

axios拦截器

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

axios.interceptors //全局拦截
instance.interceptors //实例拦截

// 请求拦截
instance.interceptors.request.use(config => {
  console.log(config);
  return config			// 拦截器有中断机制 使用之后一定要把数据结果返回出去 不然axios会响应失败					
}), err => {
  console.log(err);
})

// 响应拦截
instance.interceptors.response.use(res => {
  console.log(res);
  return res.data		// 同样需要返回, 但只需要返回data属性
}, err => {
  console.log(err);
})

什么情况下需要拦截: 1.当config中一些数据不符合服务器要求时, 拦截检查并修改返回, 防止黑客攻击,或进行错误提交 2.每次发送网络请求时, 希望在界面中显示一个请求加载的图标 3.某些网络请求, 必须携带一些特殊信息(如登录token,进行令牌验证)

在进行打项目开发时,尽量不要把所有的axios请求都塞到一个地方存放,即以后无需只面向一个request.js文件进行开发,我们可以对一个页面或者一个组件新增一个中间层的封装,方便维护与管理。

将数据保存到data里 就不会被销毁

axios放在Created还是Mounted?

如果把所有请求放在created里面的话,请求过多会,加载太慢会导致页面出现短暂的白屏情况,一般的话

接口不复杂会放created里面,

接口多复杂的话会放在mounted里面.