当前位置 : 主页 > 网络编程 > JavaScript >

vue中使用Axios最佳实践方式

来源:互联网 收集:自由互联 发布时间:2023-02-08
目录 1.前言 2.使用 2.1安装 2.2基本用例 2.2.1 get请求 2.2.2post请求 3.配置 3.1语法 3.2别名 4.Axios实例 4.1语法 4.2请求配置 4.3响应的配置 配置的优先级 5.拦截器 6.错误拦截 7.取消请求 8.完整封
目录
  • 1.前言
  • 2.使用
    • 2.1安装
    • 2.2基本用例
      • 2.2.1 get请求
      • 2.2.2post请求
  • 3.配置
    • 3.1语法
      • 3.2别名
      • 4.Axios实例
        • 4.1语法
          • 4.2请求配置
            • 4.3响应的配置
              • 配置的优先级
              • 5.拦截器
                • 6.错误拦截
                  • 7.取消请求
                    • 8.完整封装 建立http.ts文件编写clas Http类
                      • 9.总结

                        1.前言

                        最近在写vue3的项目,需要重新搭建脚手架并且使用网络请求接口,对于js的网络请求接口的一般有几种常用的方式:

                        • fetch
                        • XMLHttpRequests
                        • ajax (原生)
                        • axios (开源)

                        Axios 是一个基于 promise 的网络请求库,可以用于浏览器和 node.js。Axios 使用简单,包尺寸小且提供了易于扩展的接口。在服务端它使用原生 node.jshttp模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。

                        简单示例:

                        import axios from "axios";
                        axios.get('/users')
                        .then(res => {
                        console.log(res.data);
                        });

                        2.使用

                        2.1安装

                        npm install axios

                        2.2基本用例

                        在commonJs中使用axios时候:使用require()导入的时候获得ts的类型推断;使用以下方法:

                        const axios = require('axios').default;

                        // axios.<method> 能够提供自动完成和参数类型推断功能

                        2.2.1 get请求

                        发送一个get请求

                        import axios from "axios"; 
                        axios
                            .get("/getData")
                            .then((res) => {
                              console.log(res);
                              list.value = res.data.list;
                            })
                            .catch(function (error) {
                              // 处理错误情况
                              console.log(error);
                            })
                            .then(function () {
                              // 总是会执行
                            });

                        支持异步操作async/await用法

                        const list = ref<ListModel[]>([]);
                        async function getUrl() {
                          const res = await axios.get("/getData", {
                            params: {
                              id: 1, //需要携带参数
                            },
                          });
                          list.value = res.data.list;
                        }
                        getUrl();

                        2.2.2post请求

                        发送一个post请求

                        function postUrl() {
                          axios
                            .post("/postData", {
                              name: "Fred",
                              age: 18,
                            })
                            .then(function (response) {
                              console.log(response.data.message);
                            })
                            .catch(function (error) {
                              console.log(error);
                            });
                        }
                        postUrl();

                        发起多个并发请求

                        // 发送多个并发请求
                        function getUserInfo() {
                          return axios.get("/userInfo");
                        }
                        function getToken() {
                          return axios.get("/getToken");
                        }
                        //同步
                        Promise.all([getUserInfo(), getToken()]).then((res) => {
                          console.log(res, "res");
                        });
                        //异步
                        Promise.race([getUserInfo(), getToken()]).then((res) => {
                          console.log(res, "res1111");
                        });

                        3.配置

                        3.1语法

                        axios(config)

                        // 发起一个post请求

                        axios({ method: 'post', url: '/user/12345', data: { firstName: 'Fred', lastName: 'Flintstone' } });

                        默认请求方式:

                        // 发起一个 GET 请求 (默认请求方式) axios('/user/12345');

                        3.2别名

                        axios.request(config)

                        4.Axios实例

                        4.1语法

                        axios.create([config])

                        const instance = axios.create({
                          baseURL: 'https://some-domain.com/api/',
                          timeout: 1000,
                          headers: {'X-Custom-Header': 'foobar'}
                        });

                        4.2请求配置

                        这些是创建请求时可以用的配置选项。只有url是必需的。如果没有指定method,请求将默认使用GET方法。

                        {
                          // `url` 是用于请求的服务器 URL
                          url: '/user',
                         
                          // `method` 是创建请求时使用的方法
                          method: 'get', // 默认值
                         
                          // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
                          // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
                          baseURL: 'https://some-domain.com/api/',
                         
                          // `transformRequest` 允许在向服务器发送前,修改请求数据
                          // 它只能用于 'PUT', 'POST' 和 'PATCH' 这几个请求方法
                          // 数组中最后一个函数必须返回一个字符串, 一个Buffer实例,ArrayBuffer,FormData,或 Stream
                          // 你可以修改请求头。
                          transformRequest: [function (data, headers) {
                            // 对发送的 data 进行任意转换处理
                         
                            return data;
                          }],
                         
                          // `transformResponse` 在传递给 then/catch 前,允许修改响应数据
                          transformResponse: [function (data) {
                            // 对接收的 data 进行任意转换处理
                         
                            return data;
                          }],
                         
                          // 自定义请求头
                          headers: {'X-Requested-With': 'XMLHttpRequest'},
                         
                          // `params` 是与请求一起发送的 URL 参数
                          // 必须是一个简单对象或 URLSearchParams 对象
                          params: {
                            ID: 12345
                          },
                         
                          // `data` 是作为请求体被发送的数据
                          // 仅适用 'PUT', 'POST', 'DELETE 和 'PATCH' 请求方法
                          // 在没有设置 `transformRequest` 时,则必须是以下类型之一:
                          // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
                          // - 浏览器专属: FormData, File, Blob
                          // - Node 专属: Stream, Buffer
                          data: {
                            firstName: 'Fred'
                          },
                          
                          // `timeout` 指定请求超时的毫秒数。
                          // 如果请求时间超过 `timeout` 的值,则请求会被中断
                          timeout: 1000, // 默认值是 `0` (永不超时)
                         
                          // `withCredentials` 表示跨域请求时是否需要使用凭证
                          withCredentials: false, // default
                         
                         
                          // `auth` HTTP Basic Auth
                          auth: {
                            username: 'janedoe',
                            password: 's00pers3cret'
                          },
                         
                          // `responseType` 表示浏览器将要响应的数据类型
                          // 选项包括: 'arraybuffer', 'document', 'json', 'text', 'stream'
                          // 浏览器专属:'blob'
                          responseType: 'json', // 默认值
                         
                          // `responseEncoding` 表示用于解码响应的编码 (Node.js 专属)
                          // 注意:忽略 `responseType` 的值为 'stream',或者是客户端请求
                          // Note: Ignored for `responseType` of 'stream' or client-side requests
                          responseEncoding: 'utf8', // 默认值
                         
                          // `xsrfCookieName` 是 xsrf token 的值,被用作 cookie 的名称
                          xsrfCookieName: 'XSRF-TOKEN', // 默认值
                         
                          // `xsrfHeaderName` 是带有 xsrf token 值的http 请求头名称
                          xsrfHeaderName: 'X-XSRF-TOKEN', // 默认值
                         
                          // `onUploadProgress` 允许为上传处理进度事件
                          // 浏览器专属
                          onUploadProgress: function (progressEvent) {
                            // 处理原生进度事件
                          },
                         
                          // `onDownloadProgress` 允许为下载处理进度事件
                          // 浏览器专属
                          onDownloadProgress: function (progressEvent) {
                            // 处理原生进度事件
                          },
                         
                          // `maxContentLength` 定义了node.js中允许的HTTP响应内容的最大字节数
                          maxContentLength: 2000,
                         
                          // `maxBodyLength`(仅Node)定义允许的http请求内容的最大字节数
                          maxBodyLength: 2000,
                         
                          // `validateStatus` 定义了对于给定的 HTTP状态码是 resolve 还是 reject promise。
                          // 如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),
                          // 则promise 将会 resolved,否则是 rejected。
                          validateStatus: function (status) {
                            return status >= 200 && status < 300; // 默认值
                          },
                         
                          // `maxRedirects` 定义了在node.js中要遵循的最大重定向数。
                          // 如果设置为0,则不会进行重定向
                          maxRedirects: 5, // 默认值
                         
                          // `proxy` 定义了代理服务器的主机名,端口和协议。
                          // 您可以使用常规的`http_proxy` 和 `https_proxy` 环境变量。
                          // 使用 `false` 可以禁用代理功能,同时环境变量也会被忽略。
                          // `auth`表示应使用HTTP Basic auth连接到代理,并且提供凭据。
                          // 这将设置一个 `Proxy-Authorization` 请求头,它会覆盖 `headers` 中已存在的自定义 `Proxy-Authorization` 请求头。
                          // 如果代理服务器使用 HTTPS,则必须设置 protocol 为`https`
                          proxy: {
                            protocol: 'https',
                            host: '127.0.0.1',
                            port: 9000,
                            auth: {
                              username: 'mikeymike',
                              password: 'rapunz3l'
                            }
                          },
                         
                          // see https://axios-http.com/zh/docs/cancellation
                          cancelToken: new CancelToken(function (cancel) {
                          }),
                         
                        }

                        4.3响应的配置

                        一个请求的响应包含以下信息

                        {
                          // `data` 由服务器提供的响应
                          data: {},
                         
                          // `status` 来自服务器响应的 HTTP 状态码
                          status: 200,
                         
                          // `statusText` 来自服务器响应的 HTTP 状态信息
                          statusText: 'OK',
                         
                          // `headers` 是服务器响应头
                          // 所有的 header 名称都是小写,而且可以使用方括号语法访问
                          // 例如: `response.headers['content-type']`
                          headers: {},
                         
                          // `config` 是 `axios` 请求的配置信息
                          config: {},
                         
                          // `request` 是生成此响应的请求
                          // 在node.js中它是最后一个ClientRequest实例 (in redirects),
                          // 在浏览器中则是 XMLHttpRequest 实例
                          request: {}
                        }

                        配置的优先级

                        配置将会按优先级进行合并。它的顺序是:在lib/defaults.js中找到的库默认值,然后是实例的defaults属性,最后是请求的config参数。后面的优先级要高于前面的。下面有一个例子。

                        // 使用库提供的默认配置创建实例
                        // 此时超时配置的默认值是 `0`
                        const instance = axios.create();
                         
                        // 重写库的超时默认值
                        // 现在,所有使用此实例的请求都将等待2.5秒,然后才会超时
                        instance.defaults.timeout = 2500;
                         
                        // 重写此请求的超时时间,因为该请求需要很长时间
                        instance.get('/longRequest', {
                          timeout: 5000
                        });

                        5.拦截器

                        在请求或响应被 then 或 catch 处理前拦截它们。

                        // 生成实例
                        const instance = axios.create({
                          baseURL: "/",
                          timeout: 1000,
                          headers: { "Content-Type": "multipart/form-data;charset=utf-8" },
                        });
                        // 请求的拦截器
                        instance.interceptors.request.use(
                          function (config) {
                            // 在发送请求之前做些什么
                            console.log(config, "config");
                            return config;
                          },
                          function (error) {
                            // 对请求错误做些什么
                            return Promise.reject(error);
                          }
                        );
                        // 返回的拦截器
                        instance.interceptors.response.use(
                          function (res) {
                            // 2xx 范围内的状态码都会触发该函数。
                            // 对响应数据做点什么
                            console.log(res, "res");
                         
                            return res;
                          },
                          function (error) {
                            // 超出 2xx 范围的状态码都会触发该函数。
                            // 对响应错误做点什么
                            return Promise.reject(error);
                          }
                        );

                        6.错误拦截

                        axios.get('/getData')
                          .catch(function (error) {
                            if (error.response) {
                              // 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
                              console.log(error.response.data);
                              console.log(error.response.status);
                              console.log(error.response.headers);
                            } else if (error.request) {
                              // 请求已经成功发起,但没有收到响应
                              // `error.request` 在浏览器中是 XMLHttpRequest 的实例,
                              // 而在node.js中是 http.ClientRequest 的实例
                              console.log(error.request);
                            } else {
                              // 发送请求时出了点问题
                              console.log('Error', error.message);
                            }
                            console.log(error.config);
                          });

                        使用validateStatus配置选项,可以自定义抛出错误的 HTTP code。

                        axios.get('/getData', {
                          validateStatus: function (status) {
                            return status < 500; // 处理状态码小于500的情况
                          }
                        })

                        使用toJSON可以获取更多关于HTTP错误的信息。

                        const controller = new AbortController();
                         
                        axios.get('/getData', {
                           signal: controller.signal
                        }).then(function(response) {
                           //...
                        });
                        // 取消请求
                        controller.abort()

                        7.取消请求

                        从v0.22.0以后,CancelToken取消请求的方式被弃用,Axios 支持以 fetch API 方式——AbortController取消请求:

                        const controller = new AbortController();
                         
                        axios.get('/getData', {
                           signal: controller.signal
                        }).then(function(response) {
                           //...
                        });
                        // 取消请求
                        controller.abort()

                        8.完整封装 建立http.ts文件编写clas Http类

                        完整代码如下,亲自测试通过:

                        http.ts文件全部代码如下:

                        import type { AxiosInstance, AxiosRequestConfig } from "axios";
                        import axios from "axios";
                         
                        class Http {
                          private readonly options: AxiosRequestConfig;
                          private axiosInstance: AxiosInstance;
                         
                          // 构造函数 参数 options
                          constructor(params: AxiosRequestConfig) {
                            this.options = params;
                            this.axiosInstance = axios.create(params); // 生成实例
                            this.setupInterceptors();
                          }
                          private setupInterceptors() {
                            this.axiosInstance.defaults.baseURL = "/";
                            this.axiosInstance.defaults.headers.post["Content-Type"] =
                              "application/json";
                            this.axiosInstance.interceptors.request.use(
                              (config) => {
                                if (!config.headers) {
                                  config.headers = {};
                                }
                                // config.headers.Authorization = CSRF_TOKEN;
                                return config;
                              },
                              () => {
                                return Promise.reject({
                                  code: 1,
                                  message: "请求错误,请联系管理员",
                                });
                              }
                            );
                         
                            this.axiosInstance.interceptors.response.use(
                              (response) => {
                                return Promise.resolve(response);
                              },
                              (error) => {
                                let message = "";
                                if (error.response) {
                                  switch (error.response.status) {
                                    case 2:
                                      message = "未登录,直接跳转到登录页面";
                                      break;
                                    case 3:
                                      message = "TOKEN过期,拒绝访问,直接跳转到登录页面";
                                      break;
                                    case 4:
                                      message = "请求路径错误";
                                      break;
                                    case 5:
                                      message = "系统异常,请联系管理员";
                                      break;
                                    default:
                                      message = "未知错误,请联系管理员";
                                      break;
                                  }
                                } else {
                                  if (error.code && error.code == "ECONNABORTED") {
                                    message = "请求超时,请检查网是否正常";
                                  } else {
                                    message = "未知错误,请稍后再试";
                                  }
                                }
                                return Promise.reject({
                                  code: -1,
                                  message: message,
                                });
                              }
                            );
                          }
                          /**
                           * Http get
                           * @param url 请求路径
                           * @param config 配置信息
                           * @returns Promise
                           */
                          get(url: string, config?: any): Promise<any> {
                            return new Promise((resolve, reject) => {
                              this.axiosInstance
                                .get(url, config)
                                .then((response) => {
                                  resolve(response.data);
                                })
                                .catch((error) => {
                                  reject(error);
                                });
                            });
                          }
                          /**
                           * Http post
                           * @param url 请求路径
                           * @param data 请求数据
                           * @param config 配置
                           * @returns Promise
                           */
                          post(url: string, data?: any, config?: any): Promise<any> {
                            return new Promise((reslove, reject) => {
                              this.axiosInstance
                                .post(url, data, config)
                                .then((response) => {
                                  reslove(response.data);
                                })
                                .catch((error) => {
                                  reject(error);
                                });
                            });
                          }
                        }
                        const http = new Http({
                          timeout: 1000 * 5,
                        });
                        export default http;

                        9.总结

                        个人经过vue3项目实践,配合mock数据,使用axios请求基本满足前端日常开发的请求方式,至于文件上传,下载请求,只需要修改请求类型符合前后端联调的功能就可以使用了,对于环境的配置,我们需要在base_url上面修改指定的域名环境,这种可以做成配置项,比如在process.env.NODE_ENV填写环境配置,接下来我将配合http的请求方式详细讲解网络请求的过程,谢谢大家的支持,码字不易,希望多多三连支持

                        上一篇:vue实现监听localstorage值变化
                        下一篇:没有了
                        网友评论