Vue 与服务器通信

2024-07-13 1378阅读

引言

在构建数据驱动的 Vue 应用时,与服务器的通信是核心功能之一。本文将深入介绍如何在 Vue 中使用 axios 与服务器 API 交互,并展示如何封装 API 调用、错误处理和加载状态管理,以及如何将 API 接口统一管理以提高代码的可维护性和复用性。

Vue 与服务器通信
(图片来源网络,侵删)

本章知识点:

  • 使用 axios 与服务器 API 交互
  • 处理 HTTP 请求和响应
  • 管理 API 错误和加载状态
  • 封装 HTTP 服务和使用服务工作器

    回顾

    在之前的章节中,我们学习了 Vue 的基础知识、组件化开发、状态管理、动画与过渡等。现在,我们将转向 Vue 与服务器通信的高级话题。

    使用 axios 与服务器 API 交互

    Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和 node.js 中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests, 广泛用于 Vue 应用中,以实现与服务器的异步通信。

    Axios 特性:

    • 从浏览器创建 XMLHttpRequests

    • 从 node.js 创建 http 请求

    • 支持 Promise API

    • 拦截请求和响应

    • 转换请求和响应数据

    • 取消请求

    • 超时处理

    • 查询参数序列化支持嵌套项处理

    • 自动将请求体

      序列化

      为:

      • JSON (application/json)
      • Multipart / FormData (multipart/form-data)
      • URL encoded form (application/x-www-form-urlencoded)
      • 将 HTML Form 转换成 JSON 进行请求

      • 自动转换 JSON 数据

      • 获取浏览器和 node.js 的请求进度,并提供额外的信息(速度、剩余时间)

      • 为 node.js 设置带宽限制

      • 兼容符合规范的 FormData 和 Blob(包括 node.js)

      • 客户端支持防御 XSRF

        安装 axios

        首先,确保安装了 axios 库:

        bash
        复制代码npm install axios
        

        发起 HTTP 请求

        使用 axios 发起 GET 和 POST 请求:

        javascript复制代码// GET请求
        axios
          .get("https://api.baidu.com/data")
          .then((response) => {
            console.log(response.data);
          })
          .catch((error) => {
            console.error("出错:", error);
          });
        // POST请求
        axios
          .post("https://api.baidu.com/data", { key: "value" })
          .then((response) => {
            console.log(response.data);
          })
          .catch((error) => {
            console.error("出错:", error);
          });
        

        请求和响应拦截器

        通过拦截器,我们可以统一处理请求前的配置和响应后的数据。

        实例演示

        javascript复制代码import axios from "axios";
        const instance = axios.create({
          baseURL: "https://api.baidu.com",
          timeout: 1000, //设置接口请求超时时间
        });
        instance.interceptors.request.use(
          (config) => {
            // 在发送请求之前做些什么
            return config;
          },
          (error) => {
            // 对请求错误做些什么
            return Promise.reject(error);
          }
        );
        instance.interceptors.response.use(
          (response) => {
            // 对响应数据做点什么
            return response;
          },
          (error) => {
            // 对响应错误做点什么
            return Promise.reject(error);
          }
        );
        

        管理 API 错误和加载状态

        有效的错误处理和加载状态管理能够提升用户体验。

        错误处理

        集中管理 API 错误,例如创建一个错误处理服务。

        加载状态

        使用 Vue 的响应式系统来管理加载状态。

        实例演示

        javascript复制代码// 在Vue组件中管理加载状态和错误
        data() {
          return {
            isLoading: false,
            error: null
          };
        },
        methods: {
          async fetchData() {
            this.isLoading = true;
            try {
              const response = await http.get('/data');
              // 处理数据
            } catch (error) {
              this.error = error;
              console.error('请求出错:', error);
            } finally {
              this.isLoading = false;
            }
          }
        }
        

        封装 HTTP 服务

        封装 HTTP 服务是提高代码复用性和简化 API 调用的关键步骤。

        创建 HTTP 服务模块

        javascript复制代码// httpService.js
        import axios from "axios";
        // 创建axios实例
        const instance = axios.create({
          baseURL: "https://api.baidu.com",
          timeout: 1000, //设置接口请求超时时间
          headers: { "X-Custom-Header": "foobar" },
        });
        // 请求拦截器
        instance.interceptors.request.use(
          (config) => {
            config.headers["Authorization"] = `Bearer ${localStorage.getItem("token")}`;
            return config;
          },
          (error) => {
            return Promise.reject(error);
          }
        );
        // 响应拦截器
        instance.interceptors.response.use(
          (response) => {
            return response;
          },
          (error) => {
            if (error.response && error.response.status === 401) {
              // 处理未授权错误
              console.log("未认证。。:", error.response.data);
            }
            return Promise.reject(error);
          }
        );
        export default instance;
        

        API 接口封装层

        将后端 API 接口统一管理,可以方便其他文件复用。

        创建 API 接口文件

        javascript复制代码// api.js
        // 获取用户
        export const fetchData = () => httpService.get("/users");
        // 创建用户
        export const createUser = (userData) => httpService.post("/users", userData);
        // 更新用户
        export const updateUser = (userId, userData) =>
          httpService.put(`/users/${userId}`, userData);
        // 删除用户
        export const deleteUser = (userId) => httpService.delete(`/users/${userId}`);
        

        在 Vue 组件中使用封装的 API

        javascript复制代码// UserList.vue
        import { fetchData } from "./api";
        export default {
          data() {
            return {
              users: [],
              isLoading: false,
              error: null,
            };
          },
          methods: {
            async loadUsers() {
              this.isLoading = true;
              try {
                const response = await fetchData();
                this.users = response.data;
              } catch (error) {
                this.error = error;
                console.error("请求用户出错:", error);
              } finally {
                this.isLoading = false;
              }
            },
          },
          mounted() {
            this.loadUsers();
          },
        };
        

        请求取消

        Axios 提供了两种主要的方法来取消请求,分别是使用 CancelToken 和 AbortController。

        以下是这两种方法的基本用法:

        1. 使用 AbortController
        • Axios 支持使用 AbortController 来取消请求,这是一种与 fetch API 类似的取消方式。
        • 创建一个 AbortController 实例,并将其 signal 属性传递给 Axios 请求的 signal 配置项。
        • 调用 abort 方法来取消请求。

          javascript复制代码const controller = new AbortController(); // 创建 AbortController 实例

          axios

          .get(“/foo/bar”, {

          signal: controller.signal, // 将 signal 传递给请求

          })

          .then(function (response) {

          // 请求成功处理

          })

          .catch(function (error) {

          // 请求失败处理

          });

          // 取消请求

          controller.abort();

          1. 使用 CancelToken(官方已经弃用了)
          • 首先,你需要创建一个取消标记(cancel token)。
          • 然后,将这个标记与特定的请求关联。
          • 当需要取消请求时,调用标记中的 cancel 方法。

            javascript复制代码import axios from “axios”;

            const source = axios.CancelToken.source(); // 创建取消标记

            axios

            .get(“/api/data”, {

            cancelToken: source.token, // 将取消标记与请求关联

            })

            .then((response) => {

            // 请求成功处理

            })

            .catch((error) => {

            if (axios.isCancel(error)) {

            console.log(“请求被取消”, error.message);

            } else {

            console.log(“请求出错”, error.message);

            }

            });

            // 取消请求

            source.cancel(“请求取消的原因”);

            Axios 与 Fetch 特性对比

            特性/功能AxiosFetch
            定义Axios 是一个基于 promise 的 HTTP 客户端Fetch 是浏览器提供的 API,用于发起网络请求
            浏览器兼容性需要安装 Axios 库无需额外安装,现代浏览器内置支持
            Promise基于 Promise,易于使用 async/await返回 Promise 对象,也支持 async/await
            拦截器支持请求和响应拦截器不内置拦截器,需要手动实现
            取消请求支持请求取消,使用 CancelToken 或 AbortController支持请求取消,使用 AbortController
            请求配置支持全局和局部配置配置较为简单,主要通过 options 对象
            错误处理错误处理较为简单,统一捕获需要手动检查响应状态和处理异常
            超时控制支持请求超时设置不内置超时控制,需要手动实现
            JSON 处理自动处理 JSON 数据的请求和响应需要手动处理 JSON 数据的转换
            类型支持TypeScript 友好TypeScript 支持,但需要额外配置
            测试易于测试和模拟测试和模拟较为复杂,需要额外工具
            社区和文档活跃的社区,丰富的文档和插件标准 API,文档较为官方和简洁
            使用场景适用于复杂的 HTTP 请求处理适用于简单的 HTTP 请求或需要浏览器兼容性的场景

            共同点:

            • 两者都基于 Promise,支持 async/await。
            • 两者都支持请求取消。
            • 两者都可以处理 JSON 数据。

              差异:

              • Axios 是一个第三方库,需要安装,而 Fetch 是浏览器内置的 API。
              • Axios 提供了更丰富的功能,如拦截器、请求配置、错误处理等。
              • Axios 对 TypeScript 更友好,而 Fetch 需要额外配置 TypeScript。
              • Axios 的错误处理和超时控制更为简单和直观。
              • Fetch 的配置和使用相对简单,但需要手动处理一些功能,如拦截器和超时控制。

                fetch 使用示例

                基本语法

                javascript复制代码fetch(url, options)
                  .then((response) => {
                    // 处理响应
                    if (!response.ok) {
                      throw new Error("网络响应出错");
                    }
                    return response.json(); // 假设响应是 JSON 格式
                  })
                  .then((data) => console.log(data))
                  .catch((error) => console.error("请求出错:", error));
                

                参数说明

                • url: 请求的 URL。

                • options 可选参数,可以包含以下属性:
                  • method: 请求方法,例如 GET、POST、PUT、DELETE 等。
                  • headers: 请求头对象。
                  • body: 请求体,对于 GET 和 HEAD 请求,这个属性会被忽略。
                  • mode: 请求模式,例如 cors、no-cors、same-origin。
                  • credentials: 凭证类型,例如 include、same-origin、omit。
                  • cache: 缓存模式,例如 default、no-cache、reload、force-cache。
                  • redirect: 重定向模式,例如 follow、error、manual。
                  • referrer: 引用页 URL。
                  • integrity: 子资源完整性校验值。

                    fetch 的高级配置

                    • 请求发送:通过fetch API 来发起网络请求
                    • 请求超时:通过设置一个超时计时器,并在超时时使用 AbortController 取消请求。
                    • 取消请求:通过 AbortController 实现请求的取消。
                    • JSON 处理:手动调用 .json() 方法来解析响应体中的 JSON 数据。
                    • 错误处理:通过 .catch() 捕获请求过程中的错误,并手动处理不同类型的错误。
                    • 请求配置:通过 requestOptions 对象来配置请求方法、头部等信息。
                      javascript复制代码// 1. 定义 fetch 请求函数
                      function fetchData(url, options = {}) {
                        const controller = new AbortController(); // 支持取消请求
                        const signal = controller.signal;
                        // 设置请求超时,需要手动实现
                        const timeoutId = setTimeout(() => controller.abort(), 5000); // 5秒超时
                        // 配置请求选项
                        const fetchOptions = {
                          ...options, // 允许传入自定义配置
                          signal, // 将 AbortController 的 signal 绑定到请求
                        };
                        // 发起 fetch 请求
                        return fetch(url, fetchOptions)
                          .then((response) => {
                            if (!response.ok) {
                              // 需要手动检查响应状态
                              throw new Error("网络响应出错");
                            }
                            return response.json(); // 手动处理 JSON 数据转换
                          })
                          .catch((error) => {
                            if (error.name === "AbortError") {
                              console.error("请求中止:", error.message);
                            } else {
                              console.error("请求出错:", error);
                            }
                            throw error; // 需要手动处理异常
                          });
                      }
                      // 2. 使用 fetch 请求函数
                      const url = "https://api.baidu.com/data";
                      // 配置请求选项,例如设置请求头
                      const requestOptions = {
                        method: "GET",
                        headers: {
                          "Content-Type": "application/json",
                        },
                      };
                      fetchData(url, requestOptions)
                        .then((data) => console.log("接收的数据:", data))
                        .catch((error) => console.error("请求出错:", error));
                      // 3. 取消请求
                      // 在某个条件下取消请求,例如用户点击取消按钮
                      setTimeout(() => {
                        console.log("取消请求...");
                        // 调用 AbortController 的 abort 方法取消请求
                        clearTimeout(timeoutId); // 清除超时
                        controller.abort("用户取消 "); // 取消请求
                      }, 3000); // 假设在3秒后取消请求
                      

                      结语

                      通过本站的学习,我们掌握了如何在 Vue 中使用 axios 与服务器 API 进行交互,封装 HTTP 服务,处理 HTTP 请求和响应,以及管理 API 错误和加载状态,fetch 的探索。此外,我们还学习了如何将 API 接口统一管理,以提高代码的可维护性和复用性。

                      互动交流

                      欢迎在文章下方留言,分享学习 Vue 与服务器通信的心得体会,或提出在使用过程中遇到的问题。我们将在后续的文章中提供解答和指导。

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]