一文掌握Axios:前后端数据交互仅如此简单

24 阅读9分钟

本文转载自:fangcaicoding.cn/course/12/6…

大家好!我是方才,目前是8人后端研发团队的负责人,拥有6年后端经验&3年团队管理经验

系统学习践行者!近期在系统化输出前端入门相关技术文章,期望能帮大家构建一个完整的知识体系。

如果对你有所帮助,记得一键三连!

我创建了一个编程学习交流群(扫码关注后即可加入),秉持“一群人可以走得更远”的理念,期待与你一起 From Zero To Hero!

茫茫人海,遇见即是缘分!方才兄送你ElasticSearch系列知识图谱、前端入门系列知识图谱、系统架构师备考资料!

一文掌握Axios

ps:学习 Axios需要了解最基本的HTTP知识,至少需要知晓GET/POST/PUT/DELETE等方法的基本使用;同时也需要了解json的基本知识,知晓json数据的基本格式。

能解决的问题

你写了一个很棒的**前端项目,一切顺利运行,直到你需要和后端进行数据交互时。**此时,前端的页面和后端的服务器就像是两个相隔千里的邻居,彼此之间的沟通仿佛隔着一道厚墙。你想要的数据请求和响应总是有点“卡壳”,问题重重。这时,Axios 就成了你解决问题的利器。是不是心里在想,怎么就这么巧,今天的文章正好讲这个?

今天,我们就来一起探索如何用 Axios 轻松搞定前端与后端的数据交互,且从此告别“数据请求卡壳”的困扰。

在本篇文章中,我们将系统地介绍 Axios,让你全面了解它的核心概念、基本用法及高级技巧。你将学到如何发送 GET 请求、POST 请求、处理请求和响应拦截器、处理错误等。最重要的是,我们将通过一系列简单易懂的示例,让你快速掌握如何将 AxiosVue框架结合使用,实现高效的数据请求和处理。

image-20241206000556323

什么是 Axios

Axios 是一个基于 Promise 的 HTTP 库,主要用于浏览器和 Node.js 中发送 HTTP 请求。你可以用它发送各种类型的请求(如 GET、POST、PUT、DELETE 等),并且能够轻松地处理请求和响应的数据。简单来说,它让前端和后端的“对话”变得简单且流畅。

安装 Axios

首先,打开你的项目终端,使用 npm 或 yarn 安装 Axios

npm install axios
# 或者
yarn add axios

安装完成后,你就可以在vue项目中引入并使用 Axios 了。

请求示例

发送一个 GET 请求

让我们先来看一个简单的 GET 请求示例。假设我们需要获取一个用户列表:

import axios from 'axios';

axios.get('https://api.example.com/users')
  .then(response => {
    console.log('用户列表:', response.data);
  })
  .catch(error => {
    console.error('请求出错:', error);
  });

这里的 get 方法发出了一个 GET 请求,访问 https://api.example.com/users,然后通过 .then() 获取成功的响应数据,通过 .catch() 处理请求错误。

发送一个 POST 请求

接下来,我们来发送一个 POST 请求,提交一个新的用户数据:

import axios from 'axios';

const newUser = {
  name: '方才兄',
  age: 30,
};

axios.post('https://api.example.com/users', newUser)
  .then(response => {
    console.log('创建成功:', response.data);
  })
  .catch(error => {
    console.error('创建失败:', error);
  });

在这里,我们通过 axios.post 发送了一个包含新用户数据的请求。如果请求成功,控制台会打印出响应数据;如果失败,控制台会打印出错误信息。

请求和响应拦截器

有时候,我们需要对请求和响应做一些统一的处理,比如添加请求头、统一处理错误等。Axios 提供了请求拦截器和响应拦截器来帮助我们做这些事情。

请求拦截器

请求拦截器通常用来修改请求,例如添加认证 token、设置自定义请求头等:

axios.interceptors.request.use(config => {
  // 在请求发送之前做些什么
  config.headers['Authorization'] = 'Bearer your-token';
  return config;
}, error => {
  // 对请求错误做些什么
  return Promise.reject(error);
});

响应拦截器

响应拦截器通常用来处理响应数据或错误,例如统一处理错误信息:

axios.interceptors.response.use(response => {
  // 对响应数据做些什么
  return response;
}, error => {
  // 对响应错误做些什么
  console.error('响应错误:', error.response.data);
  return Promise.reject(error);
});

错误处理

在实际开发中,网络请求总是不可避免地会遇到各种错误。例如,服务器错误、网络断开、请求超时等。Axios 为我们提供了灵活的错误处理机制。

axios.get('https://api.example.com/users')
  .then(response => {
    console.log('用户列表:', response.data);
  })
  .catch(error => {
    if (error.response) {
      // 服务器响应错误
      console.error('响应错误:', error.response.data);
    } else if (error.request) {
      // 请求未发送
      console.error('请求未发送:', error.request);
    } else {
      // 其他错误
      console.error('其他错误:', error.message);
    }
  });

通过判断 error.responseerror.requesterror.message,我们可以更精细地捕获和处理不同类型的错误。

vue中的工具类封装

我们在vue项目中,通常会统一封装工具类,更加方便在其他文件中的使用。

封装axiosInst.js

import axios from 'axios';

// 创建一个Axios实例
const axiosInst = axios.create({
    baseURL: import.meta.env.VITE_API_URL+import.meta.env.VITE_API_PATH, //.env中的VITE_APP_API参数
    timeout: 1000, // 请求超时时间(毫秒)
    headers: {
        'Content-Type': 'application/json', // 设置默认的Content-Type
    },
});

// 封装 GET 请求
const get = (url, params = {}, config = {}) => {
    return axiosInst.get(url, {
        params,
        ...config,
    });
};

// 封装 POST 请求
const post = (url, data = {}, config = {}) => {
    return axiosInst.post(url, data, config);
};

// 封装 PUT 请求
const put = (url, data = {}, config = {}) => {
    return axiosInst.put(url, data, config);
};

// 封装 DELETE 请求
const del = (url, params = {}, config = {}) => {
    return axiosInst.delete(url, {
        params,
        ...config,
    });
};

// 请求拦截器
axiosInst.interceptors.request.use(
    (config) => {
        console.debug("interceptors.request start!")
        // 在发送请求之前做些什么,比如给请求头添加Token
        const token = localStorage.getItem('token'); // 从本地存储中获取token
        if (token) {
            config.headers['Authorization'] = `Bearer ${token}`;
        }
        return config;
    },
    (error) => {
        // 处理请求错误
        return Promise.reject(error);
    }
);

// 响应拦截器
axiosInst.interceptors.response.use(
    (response) => {
        console.debug("interceptors.response start!")
        // 统一处理响应数据,例如解析响应结构
        if (response.data.code === 200) {
            return response.data.data;
        } else {
            // 可以根据具体的业务需求处理非200的情况
            return Promise.reject(response.data.message);
        }
    },
    (error) => {
        // 统一处理响应错误
        let message = '';
        if (error.response) {
            // 请求已经发出,但是服务器响应一个状态码非 2xx 的范围
            switch (error.response.status) {
                case 400:
                    message = '请求错误';
                    break;
                case 401:
                    message = '未授权,请重新登录';
                    break;
                case 403:
                    message = '拒绝访问';
                    break;
                case 404:
                    message = '请求地址出错';
                    break;
                case 500:
                    message = '服务器内部错误';
                    break;
                default:
                    message = `连接错误 ${error.response.status}`;
            }
        } else {
            // 处理断网的情况
            if (!window.navigator.onLine) {
                message = '网络已断开';
            } else {
                message = '请求失败,请稍后重试';
            }
        }
        // 可以在这里显示错误提示信息
        console.error(message);
        return Promise.reject(error);
    }
);

export default {
    axiosInst,
    get,
    post,
    put,
    del,
};

vue中使用

  • 按业务类型封装,比如说博客文章相关的articleApi.js
    • 以下示例,包括了对GET/POST/PUT/DELETE方法的封装
import axiosInst from "./axiosInst.js";

/**
 * 增删改查
 */
const pagePublicArticle = (pageReq = {}) => {
    return axiosInst.post("/article/public/page", pageReq);
}

const getArticle = (id) => {
    return axiosInst.get("/article/" + id);
}

const addArticle = (articleSaveReq = {}) => {
    return axiosInst.post("/article", articleSaveReq);
}
const editArticle = (articleSaveReq = {}) => {
    return axiosInst.put("/article", articleSaveReq);
}

const deleteArticle = (id) => {
    return axiosInst.del("/article/" + id);
}

export default {
    pageArticle,
    getArticle,
    addArticle,
    editArticle,
    deleteArticle
}
  • 以方才coding博客的搜索功能为例:在vue文件中使用articleApi.js
<script setup>
// 查询结果的容器
const searchResults = ref([]);
    
const performSearch = async () => {
  const trimmedQuery = searchStr.value.trim();
  if (!trimmedQuery) {
    searchResults.value = [];
    return;
  }
 // 调用后端api,获取查询结果
  const pagePublicArticle = await articleApi.pagePublicArticle({
    page: 1,
    pageSize: 50,
    title: trimmedQuery
  });
 // 将接口的响应报文赋值给容器
  searchResults.value = pagePublicArticle.records;
};
</script>
  • 用户交互效果:

image-20241208141056570

axiosPromise对比

axios 和 Promise 是两个不同层面的工具。Promise 是 JavaScript 内置的用于处理异步操作的对象,而 axios 是一个基于 Promise 的 HTTP 客户端库。它可以帮助我们更简单、更便捷地发送 HTTP 请求,并自动管理返回的 Promise 对象。接下来,我们详细对比 Promise 和 axios 的特点与用法。

axios 和 Promise 的关系
axios 是基于 Promise 实现的,也就是说 axios 请求返回的是一个 Promise 对象。axios 封装了 XMLHttpRequest,能够简化处理 HTTP 请求,减少手动处理 Promise 相关逻辑的繁琐代码。

Promise 和 axios 的主要区别

功能Promiseaxios
作用管理异步操作基于 Promise 封装的 HTTP 请求库
使用场景任何异步逻辑(如文件读取、定时器等)主要用于发送 HTTP 请求,常见于 API 调用
返回值提供 thencatchfinally 方法返回一个 Promise,可以直接调用这些方法
异常处理通过 catch 方法捕获内置错误拦截器,可根据 HTTP 状态码处理不同错误
扩展性需要手动封装,灵活性高内置多种配置项,如请求头、超时时间、拦截器等

Promise 的使用示例
如果不使用 axios,而是手动用 fetch 或其他 API 发起请求,代码可能会略显复杂。以下是一个使用 Promise 的 HTTP 请求示例:

// 使用 fetch 和 Promise
function getUserData(userId) {
  return fetch(`https://jsonplaceholder.typicode.com/users/${userId}`)
    .then((response) => {
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
      return response.json();
    })
    .then((data) => {
      console.log(data); // 成功时的数据
      return data;
    })
    .catch((error) => {
      console.error("请求失败:", error.message); // 捕获错误
    });
}

getUserData(1);

在这个例子中,我们用 fetch 发起请求,返回的也是一个 Promise,并通过 .then().catch() 来处理成功和失败的情况。

axios 的主要功能与优势

自动解析响应数据:axios 会自动解析 JSON 响应,而使用 fetch 需要手动调用 response.json()。 请求/响应拦截器:可以在请求发送前或响应接收后进行统一处理。例如,添加认证头或错误处理。

axios.interceptors.request.use(
  (config) => {
    config.headers.Authorization = "Bearer token";
    return config;
  },
  (error) => Promise.reject(error)
);

取消请求:axios 支持取消请求,尤其在复杂的应用中(如 React、Vue 项目),避免不必要的请求。 更好的错误处理:axios 能根据不同的 HTTP 状态码自动分类错误,使得错误处理更清晰。
配置方便:可以在实例化 axios 时设置默认配置,例如基 URL、超时时间、头信息等。
请求数据格式化:自动将请求参数格式化为查询字符串,或在 POST 请求时自动序列化 JSON 数据。

总结

  • 灵活性:Promise 是一个通用的异步操作管理工具,而 axios 是专门针对 HTTP 请求封装的库。使用 axios 可以减少异步 HTTP 请求时的代码量和复杂性。
  • 自动化处理:axios 提供请求和响应拦截器、错误处理、自动 JSON 解析等功能,适合对 HTTP 请求有大量需求的项目。
  • 简单上手:使用 axios 发起请求更简单,可以直接获得解析后的数据并处理错误,而不需要额外的代码。

axios 让基于 Promise 的 HTTP 请求更强大和便捷,在实际开发中是非常常用的选择。如果项目中大量依赖 API 请求,axios 可以大大简化代码,提高开发效率。

总结扩展

在本文中,我们已经全面介绍了 Axios 的基本使用,包括如何发送请求、处理响应、配置拦截器、处理错误等。通过本篇教程,你应该能够轻松掌握 Axios,并将它应用于自己的项目中。

接下来,你可以进一步深入学习 Axios 的更多高级特性,比如取消请求、并行请求、请求超时控制等。Axios 是一个非常强大的工具,它能够帮助你轻松应对前端与后端之间的数据交互。

记住,编程之路不止一步,方才兄始终陪伴着你,带你一起走得更远。希望你能在使用 Axios 时游刃有余,处理数据请求时如鱼得水,打破那道厚厚的“隔墙”!


希望今天的分享对你有所帮助!别忘了,前端之路,方才兄与你同行!---

近期更新计划

近期更新计划(有需要的小伙伴,记得点赞关注哟!)

  1. 输出vue、router、elementplus等前端框架技术文章,期望能帮助大家快速建立相关的知识体系;
  2. 基于vue3+springboot3的前后端分离的博客系统已经开源啦,欢迎大家star!gitee.com/fangcaicodi…

“学编程,一定要系统化”——若你也是系统学习的践行者,记得点赞关注,期待与你一起 From Zero To Hero!