HarmonyOS APP开发—"热榜"资讯聚合App,需要用到这个库

想做一个资讯聚合 App,把科技、财经、娱乐的热点一网打尽?多源请求、统一鉴权、断点下载封面图……这些活儿,@ohos/axios 一个库全包了。

📦 仓库地址:https://gitcode.com/CPF-ApplicationTPC/ohos_axios | 安装:ohpm install @ohos/axios


写在前面

"热榜"这个 App 的核心诉求很简单:一次性从三四个新闻接口拉数据,合并排序后展示。听起来不复杂,但真写起来你会发现一堆麻烦事——

  • 每个接口的鉴权头不一样,手写 http.createHttp() 每次都要重复加 header;
  • 想并行请求三个源再合并,原生回调嵌套写到崩溃;
  • 封面图要下载到本地缓存,还得带进度条;
  • 从 Web 项目迁移过来,整个网络层几乎要推倒重写。

如果有一个库,API 和前端 axios 一模一样,拦截器、Promise、FormData 全都有——那就是 @ohos/axios

这篇文章聊什么

  1. 多源并发请求——怎么用 axios.all 同时拉取多个新闻源
  2. 统一鉴权拦截器——怎么给每个请求自动带上 Token
  3. 封面图下载——怎么带进度回调把图片存到本地

App 启动

axios.all 并发请求

源A: 科技热榜

源B: 财经热榜

源C: 娱乐热榜

拦截器自动加 Token

合并 + 排序

渲染信息流

点击下载封面

axios 下载 + 进度


第一步:安装与拦截器配置

ohpm install @ohos/axios

给每个请求自动带上鉴权头,再统一兜底错误:

import axios, { AxiosResponse, AxiosError } from '@ohos/axios'

// 请求拦截器:自动加 Token
axios.interceptors.request.use((config) => {
  config.headers['Authorization'] = 'Bearer ' + getToken()
  return config
})

// 响应拦截器:统一处理 401
axios.interceptors.response.use(
  (response) => response,
  (error: AxiosError) => {
    if (error.response?.status === 401) {
      console.warn('Token 过期,跳转登录')
    }
    return Promise.reject(error)
  }
)

这一步搞定后,后面所有请求都自动带 Token、自动兜底 401,业务代码里再也不用重复写鉴权逻辑。


第二步:多源并发拉取热榜

"热榜"的核心是同时请求多个新闻源。用 axios.all 并发,axios.spread 展开结果:

interface NewsItem {
  title: string
  source: string
  hot: number
  cover: string
}

// 同时请求三个新闻源
axios.all([
  axios.get<NewsItem[], AxiosResponse<NewsItem[]>, null>('https://api.a.com/tech'),
  axios.get<NewsItem[], AxiosResponse<NewsItem[]>, null>('https://api.b.com/finance'),
  axios.get<NewsItem[], AxiosResponse<NewsItem[]>, null>('https://api.c.com/entertainment'),
]).then(axios.spread((techRes, financeRes, entRes) => {
  // 合并三个源的数据
  const allNews = [
    ...techRes.data,
    ...financeRes.data,
    ...entRes.data,
  ].sort((a, b) => b.hot - a.hot) // 按热度排序

  console.info(`合并 ${allNews.length} 条热点`)
}))

如果你写过前端 axios,这段代码应该一眼就懂——API 完全一致,改个 import 就能跑


第三步:封面图下载带进度

用户点击一条新闻,下载高清封面图到本地缓存:

import fs from '@ohos.file.fs'

const filePath = getContext(this).cacheDir + '/cover_' + Date.now() + '.jpg'
try { fs.accessSync(filePath); fs.unlinkSync(filePath) } catch (e) {}

axios({
  url: newsItem.cover,
  method: 'get',
  filePath: filePath,
  onDownloadProgress: (e) => {
    const percent = e?.total ? Math.ceil(e.loaded / e.total * 100) : 0
    console.info(`封面下载: ${percent}%`)
  },
}).then((res) => {
  console.info('封面已保存: ' + filePath)
  // 用 filePath 渲染本地图片
})

为什么"热榜"选了 axios?

需求 原生 http @ohos/axios
多源并发 手写 Promise.all + 回调 axios.all 一行搞定
统一鉴权 每次手动加 header 拦截器自动加
错误兜底 每个请求各写 catch 响应拦截器统一处理
文件下载 手写流式处理 filePath + 进度回调
Web 迁移 全部重写 改个 import 即可

总结

"热榜"这个场景里,@ohos/axios 解决了三件事:

  1. 并发请求——axios.all + axios.spread,多源合并一行代码
  2. 统一鉴权——拦截器自动加 Token,401 自动跳登录
  3. 文件下载——filePath + onDownloadProgress,进度条开箱即用

如果你也在做资讯类、社交类、电商类 App,只要涉及网络请求,@ohos/axios 几乎是不用思考的选择。会写前端的人,5 分钟就能上手。

Logo

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

更多推荐