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

完整项目下载地址

相关推荐
yayaer237 分钟前
GOOSE 协议中MAC配置
服务器·网络·goose
嵌入式在学无敌大神1 小时前
IP协议、以太网包头及UNIX域套接字
网络·tcp/ip·unix
半青年1 小时前
华为鸿蒙电脑能否作为开发机?开发非鸿蒙应用?
ide·华为·编辑器·电脑·idea·harmonyos·visual studio
小突突突2 小时前
个人博客系统测试报告
运维·网络·功能测试
triticale2 小时前
【Java】网络编程(Socket)
java·网络·socket
wanhengidc3 小时前
服务器中存储空间不足该怎么办?
运维·服务器·网络
soulermax3 小时前
数字ic后端设计从入门到精通4(含fusion compiler, tcl教学)CMOS VLSI Design
网络·硬件架构
bestadc4 小时前
鸿蒙 核心与非核心装饰器
harmonyos
bing_1584 小时前
什么是IoT长连接服务?
网络·物联网·长连接服务
@兔然暴富@5 小时前
#跟着若城学鸿蒙# HarmonyOS NEXT学习之AlphabetIndexer组件详解
harmonyos