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 类里。等哪天要换域名、加签名、统一埋点,你会感谢今天做了封装的自己。

相关推荐
aixingkong92120 小时前
AI超节点Scale Up域总线各层优化设计
linux·服务器·网络
组合缺一1 天前
Solon 的 10 种 HTTP 服务器:改一行依赖,换一个引擎
java·服务器·网络协议·http·solon
瓦学妹1 天前
为什么您的AI总是显示“不支持的区域”?如何解决?
大数据·网络·人工智能
coward911 天前
千兆以太网卡(Ethernet)驱动初始化完成,但是无法udhcpc获取ip
服务器·网络·嵌入式硬件·tcp/ip
AI人工智能+电脑小能手1 天前
【大白话说Java面试题 第211题】【10_网络协议篇】第2题:说一下什么是 HTTP 协议?
java·网络协议·http·https·web通信
软件技术员1 天前
SSL.com 证书:免费单域名 90 天证书
网络·网络协议·ssl
腾霄星月1 天前
内网横向移动全套实操重点知识总结
网络·安全·网络安全
茉莉玫瑰花茶1 天前
IP 分片和组装的具体过程
服务器·网络·tcp/ip
nvd111 天前
GCP 7层 外部 HTTP 负载均衡器深度解析
网络协议·http·负载均衡
悟天特斯1 天前
智慧园区安防一体化:从视频AI到多系统联动的技术实践
网络·人工智能