当前位置: 首页 > article >正文

【HarmonyOS Next】封装一个网络请求模块

【HarmonyOS Next】封装一个网络请求模块

在这里插入图片描述

环境准备

在开始之前,确保你已经安装了以下依赖:

  • @ohos/axios:用于发起 HTTP 请求。
  • @ohos.router:用于页面跳转。
  • @kit.ArkUI:用于显示提示信息。
  • @kit.ArkTS:用于 JSON 操作。

安装方法:

npm install @ohos/axios @ohos.router @kit.ArkUI @kit.ArkTS

封装步骤

1. 导入依赖

首先,我们需要导入所需的模块:

import axios, { InternalAxiosRequestConfig, AxiosResponse, AxiosError, AxiosRequestConfig, AxiosInstance } from '@ohos/axios';
import router from '@ohos.router';
import { promptAction } from '@kit.ArkUI';
import PreferencesUtils from './PreferencesUtils';
import { JSON } from '@kit.ArkTS';

2. 定义 API 响应接口

为了更好地处理 API 响应,我们定义一个泛型接口 ApiResponse

interface ApiResponse<T> {
  data: T;
  message?: string;
  code?: string; // 统一为字符串类型
  msg?: string;
}

3. 创建 axios 实例

创建一个 axios 实例,并设置基础 URL、超时时间和默认请求头:

const instance: AxiosInstance = axios.create({
  baseURL: 'https://zhdj.changhong.com',
  timeout: 10000, // 10秒超时
  headers: { 'Content-Type': 'application/json' },
});

4. 设置请求拦截器

在请求发送前,我们可以对请求配置进行修改,例如添加 token 和其他公共请求头:

instance.interceptors.request.use(async (config: InternalAxiosRequestConfig) => {
  console.log('instance.interceptors.request:', JSON.stringify(config));

  // 从 PreferencesUtils 中异步获取 token
  const token = await PreferencesUtils.get("token");
  console.log('instance.interceptors.request:token:', token);

  if (token) {
    config.headers['Authorization'] = "Bearer " + token; // 设置 token
    config.headers['System-id'] = "3";
  }

  return config;
}, (error: AxiosError) => {
  // 请求错误处理
  return Promise.reject(error);
});

5. 设置响应拦截器

在响应返回后,我们可以对响应数据进行处理,例如根据状态码显示提示信息或跳转到登录页面:

instance.interceptors.response.use((response: AxiosResponse) => {
  console.log('cwx-response:', JSON.stringify(response));

  // 根据项目的实际情况处理响应
  if (response?.data?.code === '500') {
    promptAction.showToast({
      message: response.data.message, // 修正拼写错误
      duration: 500,
      alignment: Alignment.Center
    });
    return Promise.reject(response.data);
  }

  if (response?.data?.code === '200') {
    return Promise.resolve(response.data);
  }

  return response.data;
}, (error: AxiosError) => {
  console.log('AxiosError:', JSON.stringify(error.response));

  const status = error.response?.status;
  switch (status) {
    case 401: // 无权限未登录
      router.pushUrl({
        url: 'pages/login'
      });
      break;
    default:
      promptAction.showToast({
        message: '系统异常,请稍后再试!',
        duration: 2000,
        alignment: Alignment.Center
      });
      break;
  }

  return Promise.reject(error);
});

6. 封装请求方法

最后,我们将所有逻辑封装在一个泛型函数中,以便在应用中方便地调用:

// 暴露封装请求--每次调用这个方法时,不会重复添加拦截器
export default <T>(config: AxiosRequestConfig): Promise<ApiResponse<T>> => {
  return instance(config);
};

使用示例

封装完成后,我们可以在应用中轻松使用这个网络请求模块。以下是一个简单的示例:

import request from './request';

const getUserInfo = async (): Promise<ApiResponse<User>> => {
  const response = await request({
    url: '/api/user/info',
    method: 'GET',
  });

  return response;
};

const postData = async (data: PostData): Promise<ApiResponse<PostResponse>> => {
  const response = await request({
    url: '/api/data/post',
    method: 'POST',
    data: data,
  });

  return response;
};

// 调用示例
getUserInfo().then(userInfo => {
  console.log('用户信息:', JSON.stringify(userInfo));
}).catch(error => {
  console.error('获取用户信息失败:', error);
});

postData({ title: '测试标题', content: '测试内容' }).then(postResponse => {
  console.log('数据提交成功:', JSON.stringify(postResponse));
}).catch(error => {
  console.error('数据提交失败:', error);
});

总结

通过上述步骤,我们成功地在鸿蒙 Next 中封装了一个强大的网络请求模块。这个模块不仅简化了网络请求的代码,还通过请求和响应拦截器增强了请求的健壮性和用户体验。


附录:完整代码

import axios, { InternalAxiosRequestConfig, AxiosResponse, AxiosError, AxiosRequestConfig, AxiosInstance } from '@ohos/axios';
import router from '@ohos.router';
import { promptAction } from '@kit.ArkUI';
import PreferencesUtils from './PreferencesUtils';
import { JSON } from '@kit.ArkTS';

interface ApiResponse<T> {
  data: T;
  message?: string;
  code?: string; // 统一为字符串类型
  msg?: string;
}

// 创建 axios 实例
const instance: AxiosInstance = axios.create({
  baseURL: 'https://zhdj.changhong.com',
  timeout: 10000, // 10秒超时
  headers: { 'Content-Type': 'application/json' },
});

// 设置请求拦截器
instance.interceptors.request.use(async (config: InternalAxiosRequestConfig) => {
  console.log('instance.interceptors.request:', JSON.stringify(config));

  // 从 PreferencesUtils 中异步获取 token
  const token = await PreferencesUtils.get("token");
  console.log('instance.interceptors.request:token:', token);

  if (token) {
    config.headers['Authorization'] = "Bearer " + token; // 设置 token
    config.headers['System-id'] = "3";
  }

  return config;
}, (error: AxiosError) => {
  // 请求错误处理
  return Promise.reject(error);
});

// 设置响应拦截器
instance.interceptors.response.use((response: AxiosResponse) => {
  console.log('cwx-response:', JSON.stringify(response));

  // 根据项目的实际情况处理响应
  if (response?.data?.code === '500') {
    promptAction.showToast({
      message: response.data.message, // 修正拼写错误
      duration: 500,
      alignment: Alignment.Center
    });
    return Promise.reject(response.data);
  }

  if (response?.data?.code === '200') {
    return Promise.resolve(response.data);
  }

  return response.data;
}, (error: AxiosError) => {
  console.log('AxiosError:', JSON.stringify(error.response));

  const status = error.response?.status;
  switch (status) {
    case 401: // 无权限未登录
      router.pushUrl({
        url: 'pages/login'
      });
      break;
    default:
      promptAction.showToast({
        message: '系统异常,请稍后再试!',
        duration: 2000,
        alignment: Alignment.Center
      });
      break;
  }

  return Promise.reject(error);
});

// 暴露封装请求--每次调用这个方法时,不会重复添加拦截器
export default <T>(config: AxiosRequestConfig): Promise<ApiResponse<T>> => {
  return instance(config);
};

http://www.kler.cn/a/385558.html

相关文章:

  • 在 Service Worker 中caches.put() 和 caches.add()/caches.addAll() 方法他们之间的区别
  • Blender进阶:图像纹理节点和映射节点
  • Coggle数据科学 | RAG编码模型对比:谁与OpenAI最为相似?
  • EasyExcel 使用多线程按顺序导出数据
  • 【项目开发 | 跨域认证】JSON Web Token(JWT)
  • 自动驾驶3D目标检测综述(一)
  • [vulnhub] DarkHole: 2
  • Android亮屏Job的功耗优化方案
  • django电商易购系统-计算机设计毕业源码61059
  • 阿里云ECS服务器使用限制及不允许做的事情
  • ai辅助开发一个简单的在线购物网站
  • VMware _ESXI安装初探
  • Kubernetes 调度器调度策略的资源分配不均问题如何解决?
  • 鸿蒙系统的优势 开发 环境搭建 开发小示例
  • 责任链模式(Chain of Responsibility Pattern)详解
  • 探索LINQ在C#中的应用:从基本查询到数据联接
  • 力扣第45题“跳跃游戏 II”
  • Qos基本原理+园区网络
  • HarmonyOS开发 - Ability往页面(Pages)中传递数据
  • 如何调整pdf的页面尺寸
  • 【TMM2024】Frequency-Guided Spatial Adaptation for Camouflaged Object Detection
  • Spring Boot实现SSM整合
  • 二维数组转一维数组提升效率方法
  • 【原创】关于触摸芯片的那些事
  • 鸿蒙网络编程系列44-仓颉版HttpRequest上传文件示例
  • ML1:sklearn env