axios库的封装和使用

261 阅读4分钟

axios库的封装和使用.png

一、前端网络请求的选择

1. 传统的Ajax是基于XMLHttpRequest(XHR)

缺点: 配置和调用方式等非常混乱, 编码麻烦

2. 使用 jQuery-Ajax

相对于传统的Ajax非常好用.

缺点: jQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理

3. Fetch API

Fetch是AJAX的替换方案,基于Promise设计,很好的进行了关注分离,有很大一批人喜欢使用fetch进行项目开发

缺点:

  1. 首先需要明确的是Fetch是一个 low-level(底层)的API,没有帮助你封装好各种各样的功能 和实现;

  2. 比如发送网络请求需要自己来配置Header的Content-Type,不会默认携带cookie等;

  3. 比如错误处理相对麻烦(只有网络错误才会reject,HTTP状态码404或者500不会被标记为reject);

  4. 不支持取消一个请求,不能查看一个请求的进度等等

4. axios

axios 是目前前端使用非常广泛的网络请求库,包括 Vue 作者也是推荐在 Vue 中使用 axios;

axios 特点:

  • 基于promise用于浏览器和node.js的http客户端
  • 支持浏览器和node.js
  • 支持promise
  • 能拦截请求和响应
  • 自动转换JSON数据
  • 能转换请求和响应数据

二、axios 基本使用

  • axios(config)
  • axios.request(config)
  • axios.get(url [, config])
  • axios.delete(url [, config])
  • axios.head(url [, config])
  • axios.post(url [, data[, config]])
  • axios.put(url [, data[, config]])
  • axios.put(url [, data[, config]])

1. axios(config)

1.1 get

1. 通过传统的url 以 ? 的形式传递参数
axios({
     	url: 'http://httpbin.org/get?id=123'
})
2. restful 形式传递参数
axios({
     	url: 'http://httpbin.org/get/123',
})
3. 通过 params 形式传递参数
axios({
     	url: 'http://httpbin.org/get',
        params: {
          name: 'why',
          age: 18
       	}
})

delete 和 get 请求传参方式相同

1.2 post

post 和 put 请求传参方式相同

axios({
	url: 'http://httpbin.org/post',
	data: {
		name: 'kobe',
		age: 18
	},
	method: 'post'
}).then(res => {
	console.log(res);
}).catch(err => {
    	console.log(err);
});

1.3 async await 异常处理

使用 try catch 来捕获异常

async componentDidMount() {
    try {
      const result = await axios.get("http://httpbin.org/get", {
        params: {
          name: "lilei",
          age: 30,
        },
      });
      console.log(result);
    } catch (err) {
      console.log(err);
    }
  }

2. axios.request(config)

 axios.request({
        url: "http://httpbin.org/get",
        params: {
          name: "why",
          age: 18,
        },
      })

3. axios.get(url [, config])

  • 通过传统的url 以 ? 的形式传递参数
  • restful 形式传递参数
  • 通过 params 形式传递参数
axios.get('http://localhost:3000/axios', {
      params: {
        id: 789
      }
    }).then(function(ret){
      console.log(ret.data)
    })

4. axios.delete(url[, config])

delete 请求传参的形式和 get 请求一样

axios.delete('http://localhost:3000/axios', {
      params: {
        id: 111
      }
    }).then(function(ret){
      console.log(ret.data)
    })

6. axios.post(url[, data[, config]])

6.1 通过选项传递参数

axios.post('http://localhost:3000/axios', {
      uname: 'lisi',
      pwd: 123
    }).then(function(ret){
      console.log(ret.data)
    })

6.2 通过 URLSearchParams 传递参数

var params = new URLSearchParams();
params.append('uname', 'zhangsan');
params.append('pwd', '111');
 
axios.post('http://localhost:3000/axios', params).then(function(ret){
      console.log(ret.data)
})

7. axios.put(url[, data[, config]])

axios delete 请求传参的形式和 get 请求一样

axios.put('http://localhost:3000/axios/123', {
      uname: 'lisi',
      pwd: 123
}).then(function(ret){
      console.log(ret.data)
})

三、 axios 配置信息

1. axios 全局配置

1. 默认请求接口

axios.defaults.baseURL = 'https://api.example.com';

2. 配置超时时间

axios.defaults.timeout = 2500;

3. 配置公共的请求头

axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;

4. 配置公共的 post 的 Content-Type

axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

2. 自定义实例配置

const instance = axios.create({
    baseURL: BASE_URL,
    timeout: TIMEOUT
});

instance.defaults.headers.common['Authorization'] = AUTH_TOKEN

四、 axios 拦截器

1. 请求拦截器

请求拦截器的作用是在请求发送前进行一些操作

1.1 使用场景

  • 发送网络请求时,在页面中添加一个loading组件作为动画
  • 某一些请求要求用户必须携带,如果没有携带,那么直接跳转到登录页面
  • 对某些请求参数进行序列化

1.2 使用方法

axios.interceptors.request.use(回调函数1, 回调函数2)
axios.interceptors.request.use(config => {
    // 1. 发送网络请求,在界面的中间位置显示 Loading 的组件
    // 2. 某一些请求要求用户必须携带,如果没有携带,那么直接跳转到登录页面
    // 3. parms/data 序列化的操作
    //  这里一定要return   否则配置不成功 
    return config;
}, function(err){
    // 4. 对请求错误做点什么    
    console.log(err)
});

2. 请求拦截

2.1 使用场景

  • 响应拦截中可以对结果进行二次处理(比如服务器真正返回的数据其实是在response的data中)
  • 对于错误信息进行判断,根据不同的状态进行不同的处理;

2.2 使用方法

axios.interceptors.response.use(回调函数1, 回调函数2)
axios.interceptors.response.use(res => {
	return res.data; 
}, err => {
	if (err && err.response) {
		switch(err.response.status) {
			case 400:
				console.log("请求错误");
			case 401:
				console.log("未授权访问");
		}		
	}
})

四、对 axios 进行二次封装

1. 为什么要二次封装?

直接使用 axios, 如果 axios 出现 bug 无法修复, 这时我们会寻找一个新的网络请求库或者自己进行封装一个, 但项目中有多处依赖 axios, 不利于修改,所以我们就要对 axios 进行二次封装

2. 封装 axios

// config.js 配置文件
const devBaseURL = "http://123.207.32.32:9001";
const proBaseURL = "http://123.207.32.32:9001";
export const BASE_URL = process.env.NODE_ENV === 'development' ? devBaseURL : proBaseURL;

export const TIMEOUT = 5000;
// request.js
import axios from 'axios';

// 导入配置
import { BASE_URL, TIMEOUT } from './config';

// 自定义实例默认配置
const instance = axios.create({
    baseURL: BASE_URL,
    timeout: TIMEOUT
})

// 请求拦截
instance.interceptors.request.use(config => {
    return config;
})

// 响应拦截
instance.interceptors.response.use(res => {
    return res.data;
}, err => {
    if (err && err.response) {
        switch(err.response.status) {
            case 400:
                console.log('请求错误');
                break;
            case 401:
                console.log('未授权访问');
                break;
            default: 
                break;    
        }
    }
});

// 导出实例
export default instance;
// 引入实例
import request from "./request";

// 发送请求
request({
    url: '/top/list',
    params: {
      idx
    }
  }).then(res => {
  	console.log(res);
  });