React中axios的使用

803 阅读3分钟

目前前端中发送网络请求的方式有很多种:

  • 选择一: 传统的Ajax是基于XMLHttpRequest(XHR)
  • 选择二: jQuery-Ajax(基本不用了)
  • 选择三: Fetch API
  • 选择四: axios

Fetch API

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

但是Fetch的缺点也很明显,首先需要明确的是Fetch是一个low-level(底层)的API,没有帮助你封装好各种各样的功能和实现。比如发送网络请求需要自己来配置Header的Content-Type,不会默认携带cookie等。比如错误处理相对麻烦(只有网络错误才会reject,HTTP状态码404或者500不会被标记为reject)。比如不支持取消一个请求,不能查看一个请求的进度等等。MDN Fetch学习地址:developer.mozilla.org/zh-CN/docs/…

axios

axios是目前前端使用非常广泛的网络请求库,包括Vue作者也是推荐在vue中使用axios。主要特点包括:在浏览器中发送 XMLHttpRequests 请求、在 node.js 中发送 http请求、支持 Promise API、拦截请求和 响应、转换请求和响应数据等等。我们建议使用axios。

安装 与 平时的业务场景

yarn add axios

平时的业务场景 image.png 代码演示

import React, { PureComponent } from 'react'
import axios from 'axios'
export default class App extends PureComponent {
  constructor(props){
    super(props)
    this.state = {
      products:[]
    }
  }
  //拿到数据
  componentDidMount(){
    // this.setState({
    //   products:[...this.state.products,...res]

    // })
    //1.axios发送基本的网络请求
    axios({
      url:'http://httpbin.org/get',
      params:{
        name:'harry',
        age:18
      }

    }).then(res => {
      console.log(res);
    }).catch(err => {
      console.log(err);
    });

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

    axios.get("http://httpbin.org/get",{
      params:{
        name:"lilei",
        age:30
      }
    }).then(console.log)

    axios.post("http://httpbin.org/post",{
      name:"lucy",age:28
    }).then(console.log)
  }
  render() {
    return (
      <div>App</div>
    )
  }
}

使用async await

image.png

  async componentDidMount(){
    // this.setState({
    //   products:[...this.state.products,...res]

    // })
    //1.axios发送基本的网络请求
    const result = await axios.get("http://httpbin.org/get",{
      params:{
        name:"lilei",
        age:30
      }
    })
    console.log(result);

  }

async await方式得通过try catch可以拿到错误信息。

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

axios.all可以合并网络请求

    const request1 = axios({
      url: "/get",
      params: { name: "why", age: 18 }
    })

    const request2 = axios({
      url: "/post",
      data: { name: "kobe", age: 40 },
      method: "post"
    })

    axios.all([request1, request2]).then(([res1, res2]) => { //对数组解构
      console.log(res1, res2);
    });

axios的默认配置

在index.js里加入

// 7.默认配置
axios.defaults.baseURL = "https://httpbin.org";
axios.defaults.timeout = 5000;
axios.defaults.headers.common["token"] = "dafdafadfadfadfas";
// axios.defaults.headers.post["Content-Type"] = "application/text";

axios创建新的实例

在开发中我们可能会请求多台服务器,这样就可以创建多个实例。

使用axios.create创建实例,并用变量接受。

   const instance1 = axios.create({ 
      baseURL: "http://coderwhy.xyz",
      timeout: 5000,
      headers: {

      }
    })

    const instance2 = axios.create({
      baseURL: "http://baidu.xyz",
      timeout: 10000,
      headers: {

      }
    })

axios 请求和响应拦截

axios支持在发送请求之前对请求拦截。

响应拦截一般用于处理错误。

   // 请求拦截
    axios.interceptors.request.use(config => {
      // 1.发送网络请求时, 在界面的中间位置显示Loading的组件

      // 2.某一些请求要求用户必须携带token, 如果没有携带, 那么直接跳转到登录页面

      // 3.params/data序列化的操作
      console.log("请求被拦截");

      return config; //配置信息一定要return
    }, err => {

    });
    
    axios.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:
            console.log("其他错误信息");
        }
      }
      return err;
    });

对axios进行二次封装

axios最好自己手动封装。

image.png

//config.js
const devBaseURL = "https://httpbin.org"
const proBaseURL = "https://xxxxxx.org"

//判断是不是开发环境 (开发/生成)
export const BASE_URL = process.env.NODE_ENV === 'development' ? devBaseURL:proBaseURL;

export const TIMEOUT = 5000

//config.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 => {
  // 1.发送网络请求时, 在界面的中间位置显示Loading的组件

  // 2.某一些请求要求用户必须携带token, 如果没有携带, 那么直接跳转到登录页面

  // 3.params/data序列化的操作
  console.log("请求被拦截");

  return config;
}, err => {

});

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:
        console.log("其他错误信息");
    }
  }
  return err;
});

export default instance;

如果想要使用

import request from '@network/request' //导入

request({
   url:'' 
   ........
   .......
})

自己也可以根据需求再次封装。