鸿蒙Harmony应用开发,数据驾驶舱网络请求(Axios) 封装

鸿蒙Harmony应用开发,数据驾驶舱网络请求(Axios) 封装

在进行网络请求的封装之前,先来分析一下我们项目所用到的接口的基本情况: 1. 在请求的接口中添加了签名。

2.在非登录接口中添加了token。 基于以上基本的情况。我们开始来对Axios做封装。

首先我们需要在根目录的oh-package.json5文件的dependencies中添加 axios的依赖

"@ohos/axios": "^2.1.1",

前面我们已经介绍了我们的接口请求中的2个必要因素是签名和token,现在我们开始对这2块的实现开始介绍

  • 签名的生成

    我们的签名是将当前所有的请求参数加上当前的时间戳来生成的签名,所以们把请求中的参数做遍历放到一个数组中

    在添加一个当前时间戳,以及生成的签名作为新的请求参数

    private generateSignature(params: RequestParams): RequestParams {
    const time = Date.now().toString().substr(0, 10);
    let str = pref + "&";

    const allParams: RequestParams = {};
    Object.keys(params).forEach((key) => {
    allParams[key] = params[key];
    });
    allParams['timestamp'] = time;

    const sortedKeys = Object.keys(allParams).sort();

    sortedKeys.forEach((key) => {
    const value = allParams[key];
    if (typeof value !== 'object' && value !== null) {
    if (key === "timestamp") {
    str += ${key}=${time}&;
    } else if (key !== "sign") {
    str += ${key}=${decodeURIComponent(String(value))}&;
    }
    }
    });
    str += suff;
    allParams['sign'] = CryptoJS.MD5(str).toString()
    return allParams
    }

  • 请求头token

    我们在登录接口获取到token后存储到preferences中,然后在再请求头添加类似的代码

    headers.set('Authorization', token);
    

接下来我们创建一个PolarisHttp.ets开始对基本的get ,post ,put,patch等方法的封装

首先我们需要创建一个网络请求对象 PolarisHttpRequest,定义基础的变量

config: HttpRequestConfig;  //请求配置参数
interceptorHooks?: InterceptorHooks; //拦截器
instance: AxiosInstance; //阿修罗实例

阿修罗网络请求核心代码:

request<T = CommonType>(config: HttpRequestConfig): Promise<T> {
  return new Promise<T>((resolve, reject) => {
    this.instance
      .request<CommonType, T>(config)
      .then(res => {
        resolve(res);
      })
      .catch((err: Error) => {
        LogUtils.error("网络请求Request异常:", err.toString());
        if (err instanceof AxiosError) {
          showToast(err.message)
        }
        reject(err);
      });
  });
}
  • GET 请求封装:

    public get<T = CommonType>(config: HttpRequestConfig): Promise<T> {
      // 确保 params 存在
      if (!config.params) {
        config.params = {};
      }
    ​
      const allParams: RequestParams = this.generateSignature(config.params);
      // Object.keys(config.params).forEach(key => {
      //   allParams[key] = config.params[key];
      // });
      // 创建新的 headers 对象
      const headers = new AxiosHeaders(config.headers);
      return new Promise<T>((resolve, reject) => {
        const getTokenAndSendRequest = () => {
          if (!config.isLoginState) {
            UserLoginHelper.getUserToken().then(token => {
              if (token && typeof token === 'string') {
                LogUtils.error('网络请求Request Authorization', token);
                headers.set('Authorization', token);
              } else {
                LogUtils.error('网络请求Request 请求未获取的Token信息');
              }
              sendRequest();
            }).catch(reject);
          } else {
            sendRequest();
          }
        };
        const sendRequest = () => {
          // 构建新的配置对象
          const newConfig: HttpRequestConfig = {
            method: 'GET',
            url: config.url,
            params: allParams,
            headers: headers,
            data: config.data,
            timeout: config.timeout,
            responseType: config.responseType
          };
          // 发送请求
          this.request<T>(newConfig).then(resolve).catch(reject);
        };
        getTokenAndSendRequest();
      });
    }
    
  • POST请求封装:

    public post<T = CommonType>(config: HttpRequestConfig): Promise<T> {
      // 确保 data 存在
      if (!config.data) {
        config.data = {};
      }
      let allData: RequestParams = {};
      // 复制原有数据
      Object.keys(config.data).forEach(key => {
        allData[key] = config.data[key];
      });
      // 使用 generateSignature 方法生成签名
      allData = this.generateSignature(allData);
      // 创建新的 headers 对象
      const headers = new AxiosHeaders(config.headers);
    ​
      // 使用Promise来处理异步token获取
      return new Promise<T>((resolve, reject) => {
        const getTokenAndSendRequest = () => {
          if (!config.isLoginState) {
            LogUtils.error('网络请求Request--Authorization...token..!config.isLoginState');
            UserLoginHelper.getUserToken().then(token => {
              if (token && typeof token === 'string') {
                LogUtils.error('网络请求Request--Authorization', token);
                headers.set('Authorization', token);
              } else {
                LogUtils.error('网络请求Request--Authorization--请求未获取的Token信息');
              }
              sendRequest();
            }).catch(reject);
          } else {
            LogUtils.error('网络请求Request--Authorization...token..config.isLoginState');
            sendRequest();
          }
        };
        const sendRequest = () => {
          // 构建新的配置对象
          const newConfig: HttpRequestConfig = {
            method: 'POST',
            url: config.url,
            data: allData,
            headers: headers,
            timeout: config.timeout,
            responseType: config.responseType
          };
          // 发送请求
          this.request<T>(newConfig).then(resolve).catch(reject);
        };
        getTokenAndSendRequest();
      });
    ​
    ​
      // // 构建新的配置对象
      // const newConfig: HttpRequestConfig = {
      //   method: 'POST',
      //   url: config.url,
      //   data: allData,
      //   headers: headers,
      //   timeout: config.timeout,
      //   responseType: config.responseType
      // };
      // // 返回请求
      // return this.request<T>(newConfig);
    }
    

我们可以看到上述的get 请求和post请求都用了2次回调,因为我们的 preferences数据的获取是一个异步过程(因为js我不是很熟悉如果你有好的实现,也可以分享下) 我们需要先异步获取到token 然后在添加到请求头中当中去.

使用示例

const httpClient = new PolarisHttpRequest({
  baseURL: 'https://api.example.com',
  timeout: 5000,
  interceptorHooks: {
    requestInterceptor: (config) => {
      // 请求拦截逻辑
      return config;
    },
    responseInterceptor: (response) => {
      // 响应拦截逻辑
      return response;
    }
  }
});
​
// GET请求示例
httpClient.get<ApiResponse<UserInfo>>({
  url: '/user/info',
  params: { userId: 123 }
}).then(response => {
  console.log(response.data);
}).catch(error => {
  console.error(error);
});
​
// POST请求示例
httpClient.post<ApiResponse<LoginResult>>({
  url: '/user/login',
  data: { username: 'example', password: 'password' }
}).then(response => {
  console.log(response.data);
}).catch(error => {
  console.error(error);
});

注意事项

  1. 确保在使用前正确配置baseURL和其他必要的选项。
  2. generateSignature方法使用了特定的签名算法,请根据实际需求调整。
  3. 对于不同的环境(开发、测试、生产),可能需要不同的配置,建议使用环境变量或配置文件管理。

至此,您可以在ArkTS应用中更加方便地管理和发送HTTP请求,同时保证了请求的安全性和一致性。封装类提供的拦截器和错误处理机制可以大大简化API调用的复杂度。

完整项目下载地址

相关推荐
fantasy_arch41 分钟前
CPU性能优化-磁盘空间和解析时间
网络·性能优化
AORO_BEIDOU2 小时前
单北斗+鸿蒙系统+国产芯片,遨游防爆手机自主可控“三保险”
华为·智能手机·harmonyos
是Dream呀3 小时前
Python从0到100(七十八):神经网络--从0开始搭建全连接网络和CNN网络
网络·python·神经网络
博览鸿蒙3 小时前
鸿蒙操作系统(HarmonyOS)的应用开发入门
华为·harmonyos
kaixin_learn_qt_ing3 小时前
了解RPC
网络·网络协议·rpc
安全小王子4 小时前
Kali操作系统简单介绍
网络·web安全
Hacker_LaoYi5 小时前
【漏洞分析】DDOS攻防分析(四)——TCP篇
网络·tcp/ip·ddos
爱吃水果蝙蝠汤5 小时前
DATACOM-IP单播路由(BGP)-复习-实验
网络·网络协议·tcp/ip
Sun_12_26 小时前
SQL注入(SQL lnjection Base)21
网络·数据库