HarmonyOS7 HTTP 网络请求封装:统一拦截器实战

文章目录

前言

几乎每个 app 都要联网。但如果你在每个页面里都写一遍 httpRequest.request(...)、都手写错误处理、都手动拼 token,代码会又臭又长,改个 baseURL 要改二十处。

正确做法:封装一个统一的网络层。这篇文章我带你写一个带"请求拦截(自动加 token)、响应拦截(统一错误处理)"的 HTTP 封装,以后业务里一行调用就完事。

基础请求长啥样

HarmonyOS 推荐用 rcp(Remote Communication Kit)发请求,比老 http 模块更现代。

代码实现

typescript 复制代码
import { rcp } from '@kit.RemoteCommunicationKit'

async function getUsers(): Promise<User[]> {
  const session = rcp.createSession()
  const resp = await session.get('https://api.example.com/users')
  return resp.body as User[]
}

这是最原始写法,问题:没有 baseURL、没有 token、没有统一错误提示。下面我们一层层包。

第一层:统一 baseURL 和超时

typescript 复制代码
const BASE_URL = 'https://api.example.com'

class Http {
  private session: rcp.Session

  constructor() {
    this.session = rcp.createSession({
      baseAddress: BASE_URL,
      headers: { 'Content-Type': 'application/json' }
    })
  }

  async get<T>(path: string): Promise<T> {
    const resp = await this.session.get(path)
    return resp.body as T
  }
}

要点:

  • baseAddress 设一次 baseURL,后面只传 /users 这种相对路径。
  • 用泛型 <T> 让调用方拿到类型安全的返回,不用自己 cast。

第二层:请求拦截,自动带 token

真实接口基本都要登录态。与其每个请求手写 headers.token,不如在封装里统一加:

核心代码

typescript 复制代码
async get<T>(path: string): Promise<T> {
  const token = AppStorage.get<string>('token') ?? ''
  const resp = await this.session.get(path, {
    headers: { 'Authorization': 'Bearer ' + token }   // 自动注入
  })
  return this.handle(resp)   // 交给响应处理
}

AppStorage.get('token') 是全局存的登录 token,每次请求自动塞进 header。业务方完全不用管 token 从哪来。

第三层:响应拦截,统一错误处理

不同接口返回结构不同,但"成功/失败"的判断逻辑是共通的。集中处理:

完整示例

typescript 复制代码
private handle(resp: rcp.Response): any {
  const code = resp.statusCode
  if (code >= 200 && code < 300) {
    return resp.body    // 成功,返回数据
  }
  if (code === 401) {
    // token 过期,跳登录
    throw new Error('登录已过期,请重新登录')
  }
  throw new Error('请求失败:' + code)
}
  • 2xx 才视为成功,直接给业务数据。
  • 401 统一跳登录,不用每个页面判断。
  • 其他错误抛异常,调用方 try/catch 即可。

业务里怎么用

typescript 复制代码
const http = new Http()

async loadData() {
  try {
    this.users = await http.get<User[]>('/users')
  } catch (e) {
    promptAction.showToast({ message: (e as Error).message })
  }
}

业务代码干净得只剩"取数据 + 出错提示"两件事。这就是封装的价值:重复的逻辑沉到底层,业务只关心业务

常见误区(小白必踩)

误区 说明
token 写死在业务代码里 每处手写 headers.token,改一次要改二十处。交给封装层统一注入。
不统一错误处理 每个页面自己 if (code===401),重复又易漏。集中到响应拦截里。
忘了 await 请求是异步的,不 await 拿到的是 Promise 不是数据,bug 极难查。

下面这段代码可以直接复制到 DevEco Studio 里运行。建议你边读边敲,改一改文末「动手改一改」里的参数,亲眼看看效果。

完整可运行示例:HTTP 请求封装

http.createHttp() 包一层,统一处理 URL、错误、返回 JSON。

代码解析

typescript 复制代码
// 一个最小可用的请求封装
import { http } from '@kit.NetworkKit'

async function getJSON<T>(url: string): Promise<T> {
  const req = http.createHttp()
  try {
    const resp = await req.request(url, { method: http.RequestMethod.GET })
    if (resp.responseCode !== 200) {
      throw new Error('HTTP ' + resp.responseCode)
    }
    return JSON.parse(resp.result as string) as T
  } finally {
    req.destroy()   // 用完释放,避免句柄泄漏
  }
}

// 使用
@Entry
@Component
struct Page {
  @State tip: string = '加载中...'
  aboutToAppear() {
    getJSON<{ title: string }>('https://example.com/api')
      .then((d) => { this.tip = d.title })
      .catch((e) => { this.tip = '出错:' + e.message })
  }
  build() { Column(){ Text(this.tip) }.padding(20) }
}

你会看到什么 :进入页面自动发请求,tip 从「加载中」变成接口返回的数据;若网络异常,tip 显示具体错误。

动手改一改

  • getJSON 增加第二个参数 body,支持 POST。
  • finally 前加 console.info 打印耗时,做基础性能观测。
  • tip 初始值改成空,加一个 if (this.tip) 条件渲染骨架屏。

写在最后

网络封装这套"三层结构"------baseURL、请求拦截加 token、响应拦截统错------是我每个项目的标配。它前期多花半小时,后期省下的是成倍的维护成本。

你现在就可以把项目里散落的 httpRequest 收拢到一个 Http 类里。等哪天要换域名、加签名、统一埋点,你会感谢今天做了封装的自己。

相关推荐
风华圆舞1 小时前
鸿蒙HarmonyOS矩阵加载动效实战 —— 从「假旋转」到可复用的波前反馈组件
华为·矩阵·harmonyos·arkui·gradientspin·波前动效·oklab
hbugs0012 小时前
BPF 表达式检查器:一款免费开源的 Wireshark 捕获过滤器语法检查与可视化构建工具
网络·测试工具·开源·eve-ng·bpf
韩曙亮2 小时前
【Flutter】iOS 网络权限设置 ② ( 配置 iOS 平台可使用 HTTP 访问 | ATS 网络安全强制规范 )
网络·flutter·http·ios·https·网络权限·ats
大师兄66682 小时前
HarmonyOS7 显式动画与手势:拖拽回弹效果实现
arkui·harmonyos7·实战讲解
tiantianuser2 小时前
NVME-oF IP 设计1 :为什么要设计它?
网络·网络协议·rdma·roce v2·nvme of
笨鸟先飞的橘猫2 小时前
skynet——网络模块学习
网络·学习·skynet
kyle~2 小时前
Linux---Snap(隔离式Linux 软件分发范式)
linux·运维·网络
有毒的教程3 小时前
生产环境Socket编程落地实战指南(TCP/UDP工程化方案)
网络协议·tcp/ip·udp
pt10433 小时前
思科网络自动化入门课程介绍
运维·网络·自动化