get请求和post请求的统一封装

155 阅读2分钟

封装的原理 image.png

封装代码

import { http } from '@kit.NetworkKit'; // 导入网络请求模块
import { iLoginUserModel, iResponseModel } from '../../models/AccountModel'; // 导入登录用户模型和响应模型
import { promptAction, router } from '@kit.ArkUI'; // 导入提示行为模块

// 提取所有请求的ulr中的域名当做一个基本地址
const baseUrl = 'https://api-harmony-teach.itheima.net/'

export class HdHttp {
  // 静态的 POST 泛型方法
  // 示例调用:HdHttp.post<T>('getclock'),带参数调用:HdHttp.post<T>('clockinInfo?year=2024&month=4')
  static async post<T>(url: string, extraData?: Object) {
    try {
      const httpReq = http.createHttp(); // 创建 HTTP 请求对象

      let options: http.HttpRequestOptions = {
        method: http.RequestMethod.POST,
        header: {
          "Content-Type": "application/json" // 设置请求头
        },
        expectDataType: http.HttpDataType.OBJECT
      };

      // 如果存在额外数据,则将其追加到请求配置中
      if (extraData) {
        options.extraData = extraData;
      }

      // 从本地存储中获取用户数据
      let user = AppStorage.get('user') as iLoginUserModel;
      // 提取用户令牌
      let token = user?.token; // 可选(可空)类型
      if (token) {
        // 将用户令牌添加到请求头中的 Authorization 字段
        //options.header 可能是未定义的.TypeScript在分析代码时发现代码中可能存在未初始化options.header的情况
        if (!options.header) {
          options.header = {}; // 初始化 header 字段
        }
        options.header['Authorization'] = `Bearer ${token}`;
      }

      // 发送请求并等待响应
      url = baseUrl + url // 将用户传入的路径与基本地址拼接成一个完整的url地址,将来java后端发布接口的baseurl改变,我们只需要改变baseurl
      let res = await httpReq.request(url, options);

      // 增加服务器响应的code如果为401表示token失效,则重新登录获取新的有效token
      let resdata = res.result as iResponseModel<T>
      // 如果服务器响应回来的数据不为10000,则表示有错误,则提示出错误信息
      if (resdata.code !== 10000) {
        // 如果服务器响应回来的code为401表示token失效,应该重新登录
        if (resdata.code === 401) {
          //   token失效,重新登录
          promptAction.showToast({ message: 'token失效,请重新登录' })
          router.replaceUrl({ url: 'pages/LoginPage' })
        } else {
          promptAction.showToast({ message: resdata.message })
        }
      }
      //   4. 将服务器的数据返回
      return resdata
    } catch (err) {
      // 捕获错误并显示网络请求错误提示信息
      promptAction.showToast({ message: '网络请求错误' });
      return Promise.reject(err);
    }
  }

  // 封装get方法
  static async get<T>(url: string) {
    try {
      const httpReqeust = http.createHttp()
      let options: http.HttpRequestOptions = {
        header: {
          "Content-Type": "application/json"
        },
        expectDataType: http.HttpDataType.OBJECT
      }
      // 1.0 获取token传给服务器
      let user = AppStorage.get('user') as iLoginUserModel
      let token = user?.token
      if (token && options.header) {
        options.header['Authorization'] = `Bearer ${token}`
      }
      // 2.0 发请求
      url = baseUrl + url
      let res = await httpReqeust.request(url, options)

      //   3.0 处理响应判断code不为10000的情况和401的情况
      // 增加服务器响应的code如果为401表示token失效,则重新登录获取新的有效token
      let resdata = res.result as iResponseModel<T>
      // 如果服务器响应回来的数据不为10000,则表示有错误,则提示出错误信息
      if (resdata.code !== 10000) {
        // 如果服务器响应回来的code为401表示token失效,应该重新登录
        if (resdata.code === 401) {
          //   token失效,重新登录
          promptAction.showToast({ message: 'token失效,请重新登录' })
          router.replaceUrl({ url: 'pages/LoginPage' })
        } else {
          promptAction.showToast({ message: resdata.message })
        }
      }

      // 4.0 将服务器的数据返回
      return resdata
    } catch (err) {
      promptAction.showToast({ message: 'get请求网络异常' })
      return Promise.reject(err)
    }
  }
}

当封装完成后,后续开发再需要调用get请求和post请求时只需要调用封装好的代码即可,此封装代码在多个项目中均可通用