鸿蒙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调用的复杂度。

完整项目下载地址

相关推荐
亿林安全42 分钟前
等保测评中的常见误区及应对策略
网络·安全·web安全
亿林网络安全事业部43 分钟前
等保测评:企业如何构建安全的网络架构
网络·安全·架构
OH五星上将2 小时前
OpenHarmony(鸿蒙南向开发)——标准系统方案之瑞芯微RK3566移植案例(下)
harmonyos·内存管理·openharmony·鸿蒙开发·系统移植·鸿蒙内核·listos_m
求学者1.02 小时前
网络编程问题解答
网络
MAMA66812 小时前
一个简单的基于C语言的HTTP代理服务器的案例
c语言·网络·http
云兮Coder3 小时前
鸿蒙Harmony应用开发,数据驾驶舱 项目结构搭建
华为·harmonyos
Proxy7114 小时前
SOCKS5代理为何比HTTP代理更快?
网络·网络协议·http
大众筹码4 小时前
HarmonyOS元服务与卡片
华为·harmonyos
qq_316837754 小时前
https的连接过程
网络·网络协议·ssl