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的熟悉程度。

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

相关推荐
Moment5 分钟前
面试官:一个接口使用postman这些测试很快,但是页面加载很慢怎么回事 😤😤😤
前端·后端·面试
诗书画唱9 分钟前
【前端面试题】JavaScript 核心知识点解析(第二十二题到第六十一题)
开发语言·前端·javascript
excel15 分钟前
前端必备:从能力检测到 UA-CH,浏览器客户端检测的完整指南
前端
前端小巷子22 分钟前
Vue 3全面提速剖析
前端·vue.js·面试
悟空聊架构29 分钟前
我的网站被攻击了,被干掉了 120G 流量,还在持续攻击中...
java·前端·架构
CodeSheep30 分钟前
国内 IT 公司时薪排行榜。
前端·后端·程序员
尖椒土豆sss34 分钟前
踩坑vue项目中使用 iframe 嵌套子系统无法登录,不报错问题!
前端·vue.js
遗悲风35 分钟前
html二次作业
前端·html
江城开朗的豌豆38 分钟前
React输入框优化:如何精准获取用户输入完成后的最终值?
前端·javascript·全栈
CF14年老兵38 分钟前
从卡顿到飞驰:我是如何用WebAssembly引爆React性能的
前端·react.js·trae