在鸿蒙应用开发中,网络请求是实现应用与后端交互的关键部分。本文将详细介绍鸿蒙中的原生 http 请求和基于第三方库 axios 的网络请求,包括其使用方法和常见的封装方式。

一、原生 http 请求

(一)创建请求对象并获取结果(无参数的 get 请求)

代码实现:
// 创建请求对象
const req = http.createHttp()
// 获取结果
const res = await req.request('请求地址')

      这是最基础简单的无参数 get 请求方式,通过http.createHttp()创建请求对象,然后使用request方法发送请求并等待响应。

(二)带有参数的请求

代码实现

const res = req.request(`请求地址/path参数?xx=${encodeURIComponent(Query参数xx)}&yy=${encodeURIComponent(Query参数yy)}`,
  {
  // header参数
  header: {
             contentType: 'application/json',
    Authorization:'xxxxx'
  },
  // body参数
  extraData:{},
  // 请求类型 默认http.RequestMethod.GET
  method: xxxx
  })
const data = res.result

当需要发送带有参数的请求时,可以通过拼接字符串的方式来构建请求地址。需要注意的是,对于中文等特殊字符,需要使用encodeURIComponent进行转码,以避免出现错误。同时,可以在请求配置中设置请求头(header)、请求体(extraData)和请求类型(method)等参数,后端返回的结果在res.result中获取。

二、第三方库 axios 请求

(一)安装与卸载

在使用 axios 之前,需要先进行安装:

  • 安装:ohpm i @ohos/axios
  • 卸载:ohpm uninstall @ohos/axios

(二)基本使用

代码实现

const res = await axios
<响应类型, AxiosResponse<响应类型(优先级高), 提交类型>, 提交类型(优先级高)>
({
    url: '',
    method: '',
    data: {},
    params: {},
    headers: {}
  })
const data = res.data

使用 axios 发送请求时,传入包含请求地址(url)、请求方法(methodget请求可省略)、请求数据(data)、查询参数(params,会自动拼接到 URL 上且无需转码)和请求头(headers)等参数的对象。后端返回的结果在res.data中获取。

三、axios 封装网络请求工具

(一)不分开请求方式的封装

1. 封装基地址

const request = axios.create({baseURL:'基地址'})

2. 添加请求拦截器和响应拦截器

  • 请求拦截器
// 添加请求拦截器
request.interceptors.request.use((config:InternalAxiosRequestConfig) => {
  // 对请求数据做点什么  一般必须注入token(token存在时)
  const token =  'xxxxxxxxxxxxxxxxxxxx'  
  if(user.token){
    config.headers.Authorization = `Bearer ${user.token}`
  }
  return config;
}, (error:AxiosError) => {
  // 对请求错误做些什么
  return Promise.reject(error);
});

在请求拦截器中,通常会检查用户的 token(如果存在)并将其添加到请求头中。

  • 响应拦截器
equest.interceptors.response.use((response:AxiosResponse)=> {
  // 对响应数据做点什么   网络通信成功  判断业务通信 处理事件

  return response;
},
  (error:AxiosError)=> {
  // 对响应错误做点什么     网络通信失败 401为登录超时 处理事件
  if(error.response?.status==401){
    promptAction.showToast({message:'登录超时,请重新登录!'})

    return Promise.reject()
  }
  promptAction.showToast({message:error.message})
  return Promise.reject(error);
});

响应拦截器用于处理网络通信成功和失败的情况,例如在登录超时(401 错误)时提示用户重新登录。

3. 写请求方法,实现请求

  • 第一种写法
function otherAxiosRequest<T=null, D=null>(data:AxiosRequestConfig<D>){
  return request<null, AxiosResponse<T, null>, D>(data)
}
// data为axios的参数
// 如
interface IParams{
username:string
password:string
}
const res = await otherAxiosRequest<string, IParams>({
url:'hm/login',
data:{
  username: this.username,
  password: this.password
},
method:'post'
})
// res中的data便是后端返回的结果
const data = res.data
  • 第二种写法,

如果后端返回的数据有规律,如
export interface IRes<T>{
  /** 请求成功 10000 标志  */
  code: number;

  /** 返回数据  */
  data: T;

  /** 请求成功  */
  message: string;

  /** 请求成功标志  */
  success: boolean;
}
function axiosRequest<T=null, D=null>(data:AxiosRequestConfig<D>){
  return request<null, AxiosResponse<IRes<T>, null>, D>(data)
}

// data为axios的参数
// 如
interface IParams{
username:string
password:string
}
const res = await axiosRequest<string, IParams>({
url:'hm/login',
data:{
  username: this.username,
  password: this.password
},
method:'post'
})
// res中的data便是后端返回的IRes中data数据(返回数据)
const data = res.data

(二)分开请求方式的封装

1. 封装基地址和添加拦截器

与不分开请求方式的封装步骤 1 和 2 相同。

2. 写请求方法,实现请求

  • 新建 RequestAxios 类管理
export  class RequestAxios{
  static get<T>(url: string, params?: object): Promise<T> {
    return instance.get<null, T>(url, { params })
  }

  static put<T>(url: string, data?: object): Promise<T> {
    return instance.put<null, T>(url, data)
  }

  static post<T>(url: string, data?: object): Promise<T> {
    return instance.post<null, T>(url, data)
  }

  static delete<T>(url: string, data?: object): Promise<T> {
    return instance.delete<null, T>(url, { data })
  }
}

通过创建一个类来分别管理不同类型的请求方法(getputpostdelete),方便在不同场景下调用, data为一些必要参数,可以理解为axios的参数对象中除了method和url。

3. 调用方法获取结果

const res = await RequestAxios.get<Goods>(`xxxx`)
const res = await RequestAxios.post<SearchResult>("xxxx", 
  {
      keyword: '',
      sortField: 'publishTime',
      sortMethod: 'desc',
      page: 1,
      pageSize: 10
  } as xxx)
//res.data 便是后端返回的IRes中data数据(返回数据)

通过调用相应的请求方法来发送请求,并从res.data中获取后端返回的数据。

4. 封装为单个 API

export const getXxxAPI = async () => {
  return await RequestAxios.get<address[]>("/Xxx")
}

export const addXxxAPI = async (data:参数对象类型) => {
  return await RequestAxios.post<null>("Xxx", data)
}

export const delXxxAPI = async (id:string) => {
  return await RequestAxios.delete<null>(`Xxx${id}`)
}

export const updateXxxAPI = async (id:string,data:参数对象类型) => {
  return await RequestAxios.put<null>(`Xxx${id}`, data)
}

进一步将请求方法封装为独立的 API 函数,方便在项目中统一管理和调用。

通过上述原生 http 请求和基于 axios 的网络请求方式及其封装方法,可以高效地实现鸿蒙应用与后端的网络通信,满足不同业务场景的需求。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐