HarmonyOS NEXT - 电商App实例三( 网络请求axios)

使用axios开发网络请求是一个非常常见的任务,尤其是Web前端开发者,对它非常熟悉。axios是一个基于Promise的HTTP客户端,支持浏览器和Node.js环境,使用简单且功能强大。

在harmonyOS中,如果想使用axios,可以通过ohpn工具包下载安装。

接下来,将通过axios库,对其进行二次封装,并向后台发送请求,完成banner数据的获取。

一、基本使用

1.1 下载 ohpm工具包

HarmonyOS开发工具DevEco Studio,最新版本DevEco Studio 5.0.1 Release安装时,ohpm工具已包含。如果是版本较低,需要手动进行安装,可以查看之前写的一篇关于这方面内容,地址:HarmonyOS开发 - ohpm环境变量配置-CSDN博客

1.2 下载axios

命令如下:

TypeScript 复制代码
ohpm install @ohos/axios

安装成功后,oh_modules目录则可以看到@ohos/axios。如下图:

1.3 导入模块

TypeScript 复制代码
import axios from '@ohos/axios'

1.4 发送GET请求

首先,我们先看下@ohos/axios的基本用法,使用axios模块发送一个GET请求,处理响应。示例代码如下:

TypeScript 复制代码
// 导入模块
import axios from '@ohos/axios'

// 发送 GET 请求
axios.get('https://api.example.com/data')
    .then(response => {
        console.log('Response Data:', response.data);
    })
    .catch(error => {
        console.error('Error:', error.message);
    });

1.5 配置项

axios允许通过配置对象来自定义请求,一些常见的配置选项如下:

TypeScript 复制代码
{
    method: 'get', // 请求方法 (get, post, put, delete 等)
    url: 'https://api.example.com/data', // 请求 URL
    headers: {
        'Authorization': 'Bearer your_access_token', // 自定义请求头
        'Content-Type': 'application/json'
    },
    params: {
        key: 'value' // URL 参数 (用于 GET 请求)
    },
    data: {
        key1: 'value1',
        key2: 'value2'
    }, // 请求体 (用于 POST/PUT 请求)
    timeout: 5000 // 请求超时时间 (毫秒)
}

1.6 处理响应

参数说明如下:

|------------|--------|-----------|
| 名称 | 类型 | 描述 |
| status | number | http响应状态码 |
| statusText | string | http状态信息 |
| headers | Object | 响应头 |
| data | any | 服务端返回的响应体 |
| config | Object | 请求的配置信息 |

1.7 错误处理

参数说明如下:

|----------|--------|---------|
| 名称 | 类型 | 描述 |
| message | string | 错误信息 |
| response | Object | 服务器的响应 |
| request | Object | 请求对象 |
| config | Object | 请求的配置信息 |

二、axios库

axios是一个非常强大且易于使用的Http客户端,适用于大多数网络请求。通过掌握axios,可以轻松使用它开发网络请求,并处理各种复杂的需求。

2.1 @ohos/axios实例

如果需要为不同的API设置不的配置,可以创建一个axios实例,代码如下:

TypeScript 复制代码
import axios from '@ohos/axios'

const axiosInstance = axios.create({
  baseURL: "http://test.shop.com",
  headers: {
    'Content-Type': 'application/json'
  }
})

2.2 拦截器

axios提供了请求和响应拦截器,可以在请求发送前或响应到达后对其进行处理。

2.2.1 请求拦截器

在项目中,一些API请求需要访问令牌(即证明登录的一串字符串),为了方便,可以在拦截器中统一添加。示例代码如下:

TypeScript 复制代码
// 请求拦截器
axiosInstance.interceptors.request.use(config => {
  // 在请求发送前做一些处理
  config.headers['accessToken'] = 'kl1ad1234214dfasdfas'  // 添加访问令牌
  return config;
}, error => {
  return Promise.reject(error);
});

2.2.2 响应拦截器

在电商项目中,例如下单功能,必须为登录状态;此时,如果用户在未登录状态下点击购买,须跳转到登录界面或给用户相关提示信息;

除了下单功能,我的界面,订单列表、详单详情、我的收藏等,都是需要用户在登录状态下进行操作;所以,此时我们可以在响应拦截器中,做统一处理,当接收到登录失效或未登录的状态码时,作出相应操作。拦截器代码如下:

TypeScript 复制代码
// 响应拦截器
axiosInstance.interceptors.response.use(response => {
  // 在响应到达后做一些处理
  if (response.status == 400) {
    // 如果400表示登录失效,访问页面必须为登录状态,此时程序须做跳转到登录界面,或提示操作
  }
  return response;
}, error => {
  return Promise.reject(error);
});

2.3 any 和 unknown问题

在ArkTS中,使用 @ohos/axios 发起网络请求时,如果遇到 arkts-no-any-unknown 错误(Use explicit types instead of "any", "unknown" (arkts-no-any-unknown) <ArkTSCheck>。),说明代码中使用了 any 或 unknown 类型,而 ArkTS 要求使用显式类型以提高代码的类型安全性。

这个问题,在上篇@ohos.net.http请求封装中也存在,并将其解决。如需了解的朋友,可以前去查看,地址:HarmonyOS开发 - 电商App实例二( 网络请求http)-CSDN博客

2.4 定义接口

所以在封装axios请求前,为避免使用 any 和 unknown,并确保类型安全。将请求和响应的数据定义为明确的接口。示例代码如下:

TypeScript 复制代码
import { Method } from '@ohos/axios'

// http定义请求参数接口
interface axiosRequestOptions {
  url: string;
  method?: Method,
  headers?: Record<string, string>;
  data?: Record<string, any>;
  params?: Record<string, any>;
  timeout?: number
}

// http定义响应数据接口
interface axiosHttpResponse<T> {
  responseCode: number;
  result: T;
}

2.5 @ohos/axios封装

为了简化代码并提高复用性,可以将@ohos/axios封装成一个工具类。先在ets目录下创建utils目录,再创建axiosUtil类(路径:ets/utils/axiosUtil.ts)。使用显式类型替代 any 和 unknown,代码如下:

TypeScript 复制代码
import axios, { AxiosInstance, Method } from '@ohos/axios'
import { axiosRequestOptions } from '../types/http';

export class axiosUtil {
  private base_url: string = '';  // 基础路径
  private headers: Record<string, string> | null = null; // header信息
  private axiosRequest: AxiosInstance; // request请求

  constructor(base_url?: string, headers?: Record<string, string>) {
    this.base_url = base_url
    this.headers = headers
    // axios实例
    this.axiosRequest = axios.create({
      baseURL: this.base_url,
      headers: this.headers
    })
  }

  /**
   * 发送 http 请求
   * @param options 请求配置
   * @returns 返回响应数据
   */
  public async request<T> (options: axiosRequestOptions): Promise<T> {
    const { url, method = 'GET', headers = {}, params, data } = options;

    try {
      const response = await this.axiosRequest({
        url,
        method,
        headers,
        params,
        data
      });

      if (response.status === 200) {
        return response.data as T; // 显式类型断言
      } else {
        throw new Error(`HTTP Error: ${response.status}`);
      }
    } catch (error) {
      throw new Error(`Request Failed: ${error.message}`);
    }
  }

  /**
   * 发送 GET 请求
   * @param url 请求地址
   * @param params URL 参数
   * @param headers 请求头
   * @returns 返回响应数据
   */
  public async get<T>(url: string, params?: Record<string, any>, headers: Record<string, string> = {}): Promise<T> {
    return this.request<T>({ url, method: 'GET', headers, params });
  }

  /**
   * 发送 POST 请求
   * @param url 请求地址
   * @param data 请求体
   * @param headers 请求头
   * @returns 返回响应数据
   */
  public async post<T>(url: string, data: Record<string, any>, headers: Record<string, string> = {}): Promise<T> {
    return this.request<T>({ url, method: 'POST', headers, data });
  }
}

2.6 实例axiosUtil类

在utils目录中,再创建request请求文件(路径:ets/utils/request.ts),用于初始化http请求的基础路径和header请求类型信息。示例代码如下

TypeScript 复制代码
import { axiosUtil } from './axiosUtil'
/**
 * 初始化请求 实例类
 */
export const axiosRequest = new axiosUtil('http://test.shop.com', {
  'Content-Type': 'application/json'
})

2.7 api请求

在api目录创建,创建index.ts文件,用于定义具体业务请求函数。这里向后台发送一个GET请求,用于获取banner信息。示例代码如下:

TypeScript 复制代码
import { axiosRequest } from '../utils/request'
interface apiBanner {
  id: number;
  name: string;
  thumb: string;
  uid: number;
  createTime: Date;
  updateTime: Date;
}

/**
 * 获取banner信息
 */
export const getBannerInfo = async () => {
  return await axiosRequest.get<apiBanner>('/banner.php')
}

2.8 获取Banner信息

如下图,在页面中添加按钮,点击"获取banner信息",向后台发送GET请求,获取banner数据。

打开pages/index.ets 页面文件,添加http请求。代码如下:

TypeScript 复制代码
import { getBannerInfo } from '../api/index'

@Entry
@Component
struct Index {
  @State bannerMessage: string = '';

  build() {
    RelativeContainer() {
      Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }){
        Text(this.bannerMessage)

        Button('获取banner信息').onClick(async () => {
          console.log('tag')
          await getBannerInfo().then(res => {
            this.bannerMessage = JSON.stringify(res)
            console.log('tas success', res)
          }).catch(() => {
            console.error('Error')
          })
        })
      }.width('100%')
    }
    .height('100%')
    .width('100%')
  }
}

此时,在页面中点击按钮,获取banner信息。如下图:

三、http和axios比较

HarmonyOS中,@ohos.net.http和@ohos/axios都是用于进行网络请求的工具,它们各自具有不同的特点和适用场景。

3.1 基础概述

3.1.1 @ohos.net.http

  • HarmonyOS中用于进行HTTP网络请求的原生接口或组件。
  • 支持GET、POST、PUT、DELETE等常见的HTTP请求方法。
  • 通常用于简单的数据传输和RESTful API的交互。

3.1.2 @ohos/axios

  • Axios在HarmonyOS平台的适配版本。
  • 基于Promise的HTTP客户端,适用于浏览器和Node.js环境,同时也兼容HarmonyOS。
  • 保留了Axios的主要特性,并适配了HarmonyOS的网络API。

3.2 泛型支持

3.2.1 @ohos.net.http

  • 不直接支持泛型类型。
  • 返回的响应数据默认为string或ArrayBuffer,需要开发者手动解析和类型断言。

3.2.2 @ohos/axios

  • 通过泛型参数直接定义响应数据类型,实现编译时类型安全。
  • 提供了更好的开发体验和代码可读性。

3.3 参数传递与序列化

3.3.1 @ohos.net.http

  • 请求配置通过options对象传递,类型为HttpRequestOptions,无泛型支持。
  • 请求体使用extraData字段,类型为string或ArrayBuffer,需要手动序列化。

3.3.2 @ohos/axios

  • 请求体可以直接传递对象,Axios会根据Content-Type自动序列化为JSON。
  • 泛型配置支持通过泛型定义请求参数和响应数据类型。

在HarmonyOS中选择使用@ohos.net.http还是@ohos/axios主要取决于具体的应用场景、开发者的偏好以及对库或API的熟悉程度。

如果你有更多问题,欢迎随时沟通交流!

相关推荐
sorryhc12 分钟前
解读Ant Design X API流式响应和流式渲染的原理
前端·react.js·ai 编程
1024小神17 分钟前
vue/react前端项目打包的时候加上时间,防止后端扯皮
前端·vue.js·react.js
拉不动的猪22 分钟前
刷刷题35(uniapp中级实际项目问题-2)
前端·javascript·面试
bigcarp28 分钟前
理解langchain langgraph 官方文档示例代码中的MemorySaver
java·前端·langchain
FreeCultureBoy31 分钟前
从 VS Code 的插件市场下载扩展插件
前端
前端菜鸟日常41 分钟前
Webpack 和 Vite 的主要区别
前端·webpack·node.js
仙魁XAN1 小时前
Flutter 学习之旅 之 flutter 在设备上进行 全面屏 设置/隐藏状态栏/隐藏导航栏 设置
前端·学习·flutter
hrrrrb2 小时前
【CSS3】化神篇
前端·css·css3
木木黄木木2 小时前
HTML5拼图游戏开发经验分享
前端·html·html5
不能只会打代码3 小时前
六十天前端强化训练之第十七天React Hooks 入门:useState 深度解析
前端·javascript·react.js