HarmonyOS 基于Network Kit封装的网络请求工具

Support

  • 泛型返回结果
  • 拦截器实现
  • 全局配置header
  • 独立设置header参数

Features

  • 缓存功能
  • 取消请求

配置类型定义

基础配置

ArkTS 复制代码
export interface NetConfig {
  baseURL: string;
  timeout?: number;
  headers?: Record<string, string>;
  statusHandlers?: Record<number, string>; // 状态码映射
}

定义 Response 泛型基类

ArkTS 复制代码
export interface BaseResponse<T> {
  requestUrl: string,
  requestMethod: http.RequestMethod,
  requestHeaders: Record<string, string>,
  requestBody: string,
  code: number
  data: T
}

拦截器上下文接口

ArkTS 复制代码
interface InterceptorContext {
  url: string;
  method: http.RequestMethod;
  headers: Record<string, string>;
  data?: object;
};

拦截器基类

ArkTS 复制代码
export abstract class Interceptor {
  // 请求前调用
  async onRequest?(context: InterceptorContext): Promise<void> {
    // 子类可重写此方法
  }

  // 响应后调用
  async onResponse?<T>(response: BaseResponse<T>, context: InterceptorContext): Promise<void> {
    // 子类可重写此方法
  }
}

网络初始化配置类

ArkTS 复制代码
export class NetManager {
  static instance: NetManager;
  private config: NetConfig;

  static init(config: NetConfig) {
    if (!NetManager.instance) {
      NetManager.instance = new NetManager(config);
    }
  }

  private constructor(config: NetConfig) {
    this.config = config;
  }

  getConfig(): NetConfig {
    return this.config;
  }
}

请求接口类

ArkTS 复制代码
interface RequestOptions {
  cacheKey?: string; // 缓存标识
  showLoading?: boolean; // 显示加载框
  headers?: Record<string, string>;
};

请求工具类

ArkTS 复制代码
export class NetUtils {
  static globalInterceptors: Interceptor[] = [];

  static async request<T>(
    method: http.RequestMethod,
    url: string,
    data?: Record<string, string | number | boolean | RequestDataArray>,
    options?: RequestOptions,
  ): Promise<BaseResponse<T>> {
    const config = NetManager.instance.getConfig();
    const fullUrl = `${config.baseURL}${url}`;
    const req = http.createHttp();
    // 合并请求头:全局配置 < 单独设置的headers
    const mergedHeaders: Record<string, string> = {};

    // 手动合并全局headers(使用Object.keys)
    if (config.headers) {
      const globalHeaderKeys = Object.keys(config.headers);
      for (let i = 0; i < globalHeaderKeys.length; i++) {
        const key = globalHeaderKeys[i];
        mergedHeaders[key] = config.headers[key];
      }
    }

    // 手动合并单独设置的headers(使用Object.keys)
    if (options?.headers) {
      const optionHeaderKeys = Object.keys(options.headers);
      for (let i = 0; i < optionHeaderKeys.length; i++) {
        const key = optionHeaderKeys[i];
        mergedHeaders[key] = options.headers[key];
      }
    }

    // 请求上下文
    let context: InterceptorContext = {
      url: fullUrl,
      method,
      headers: config.headers ?? {},
      data
    };

    try {
      // 请求拦截器(添加全局Header)
      context = await NetUtils.handleRequestInterceptors(context);

      // 执行请求
      const response = await req.request(fullUrl, {
        method,
        header: context.headers,
        extraData: data,
        expectDataType: http.HttpDataType.OBJECT,
        readTimeout: config.timeout ?? 30000,
      });

      // 状态码处理(统一错误码)
      if (config.statusHandlers?.[response.responseCode]) {
        throw new Error(config.statusHandlers[response.responseCode]);
      }

      // 响应数据处理
      const result = response.result as T;
      const baseResponse: BaseResponse<T> = {
        requestUrl: fullUrl,
        requestMethod: method,
        requestHeaders: context.headers,
        requestBody: JSON.stringify(data),
        code: response.responseCode,
        data: result,
      };

      // 响应拦截器处理
      await NetUtils.handleResponseInterceptors(baseResponse, context);

      hilog.info(0, 'NetUtils', 'request', JSON.stringify(baseResponse))
      return baseResponse;
    } finally {
      req.destroy();
    }
  }

  static async handleRequestInterceptors(ctx: InterceptorContext) {
    for (const interceptor of NetUtils.globalInterceptors) {
      if (interceptor.onRequest) {
        await interceptor.onRequest(ctx);
      }
    }
    return ctx;
  }

  static async handleResponseInterceptors<T>(response: BaseResponse<T>, ctx: InterceptorContext) {
    for (const interceptor of NetUtils.globalInterceptors) {
      if (interceptor.onResponse) {
        await interceptor.onResponse(response, ctx);
      }
    }
  }

  // 添加全局拦截器
  static addInterceptor(interceptor: Interceptor) {
    NetUtils.globalInterceptors.push(interceptor);
  }
}

创建具体的拦截器子类

Log拦截器

ArkTS 复制代码
export class LoggingInterceptor extends Interceptor {
  async onRequest(context: InterceptorContext): Promise<void> {
    hilog.info(0, 'LoggingInterceptor', 'Request: ' + context.url);
  }

  async onResponse<T>(response: BaseResponse<T>): Promise<void> {
    hilog.info(0, 'LoggingInterceptor', 'Response Code: ' + response.code);
  }
}

Token拦截器 在header中添加token

ArkTS 复制代码
export class TokenInterceptor extends Interceptor {
  async onRequest(context: InterceptorContext): Promise<void> {
    // 添加token
    context.headers['token'] = AppMode.TOKEN;
  }
}
相关推荐
dalancon1 小时前
SurfaceControl 的事务提交给 SurfaceFlinger,以及 SurfaceFlinger 如何将这些数据设置到对应 Layer 的完整流程
android
dalancon1 小时前
SurfaceFlinger Layer 到 HWC 通信流程详解
android
HwJack202 小时前
HarmonyOS响应式布局与窗口监听:让界面像呼吸般灵动的艺术
ubuntu·华为·harmonyos
cccccc语言我来了2 小时前
Linux(9)操作系统
android·java·linux
yige452 小时前
【MySQL】MySQL内置函数--日期函数字符串函数数学函数其他相关函数
android·mysql·adb
洞见前行2 小时前
AI 当逆向工程师:Claude Code 自主分析 APK 和 so 文件,解决 Unity 插件化启动崩溃
android·人工智能
王码码20353 小时前
Flutter 组件 inappwebview_cookie_manager 适配 鸿蒙Harmony 实战 - 驾驭核心大 Web 容器缓存隧道、构建金融级政企应用绝对防串号跨域大隔离基座
flutter·harmonyos·鸿蒙·openharmony·inappwebview_cookie_manager
左手厨刀右手茼蒿3 小时前
Flutter 组件 ews 的适配 鸿蒙Harmony 实战 - 驾驭企业级 Exchange Web Services 协议、实现鸿蒙端政企办公同步与高安通讯隔离方案
flutter·harmonyos·鸿蒙·openharmony
努力进修3 小时前
旧安卓手机别扔!用KSWEB搭个人博客,搭配外网访问超香
android·智能手机·cpolar
钛态3 小时前
Flutter 三方库 react 泛前端核心范式框架鸿蒙原生层生态级双向超能适配:跨时空重塑响应式单向数据流拓扑与高度精密生命周期树引擎解耦视图渲染控制中枢(适配鸿蒙 HarmonyOS ohos)
前端·flutter·react.js