鸿蒙应用网络开发实战:HTTP、WebSocket、文件下载与网络检测全攻略

摘要

在现代应用开发里,网络几乎是必不可少的能力。不管是社交类应用、在线教育、还是电商购物,应用都需要和后端服务进行数据交互。鸿蒙(HarmonyOS)的 ArkTS 提供了比较完整的网络 API,包括 HTTP 请求、WebSocket 实时通讯、文件下载,以及网络状态检测。本文会带你从权限配置开始,一步步写出能跑的 Demo,并结合实际场景,展示如何在项目里高效地使用网络资源。

引言

随着鸿蒙生态逐渐成熟,越来越多的应用需要接入远程服务:

  • App 启动时要拉取配置;
  • 用户操作时需要发送请求更新数据;
  • 大文件需要下载保存到本地;
  • 聊天、推送等场景则离不开实时连接。

如果你刚接触鸿蒙的网络 API,可能会有点摸不清套路:权限怎么配?HTTP 和 WebSocket 怎么写?网络断了要怎么感知?接下来我们就通过一个完整的工具模块,把这些问题都跑通。

基础准备:权限配置

module.json5 里声明权限,这是应用能否访问网络的前提:

jsonc 复制代码
{
  "module": {
    "requestPermissions": [
      { "name": "ohos.permission.INTERNET" },
      { "name": "ohos.permission.GET_NETWORK_INFO" }
    ]
  }
}

封装一个网络工具模块

我们先写一个 NetUtils.ets 模块,把常用的操作都放在一起,后续用的时候直接导入。

ts 复制代码
// NetUtils.ets
import http from '@ohos.net.http'
import fs from '@ohos.file.fs'
import websocket from '@ohos.net.websocket'
import connectivity from '@ohos.net.connectivity'

const client = http.createHttp()

// GET 请求
export async function getJson<T>(url: string): Promise<T> {
  const res = await client.request(url, {
    method: http.RequestMethod.GET,
    header: { 'Accept': 'application/json' },
    connectTimeout: 5000,
    readTimeout: 8000,
  })
  if (res.responseCode !== 200) throw new Error(`HTTP ${res.responseCode}`)
  return JSON.parse(res.result as string)
}

// POST 请求
export async function postJson<T>(url: string, data: Record<string, unknown>): Promise<T> {
  const res = await client.request(url, {
    method: http.RequestMethod.POST,
    header: { 'Content-Type': 'application/json' },
    extraData: JSON.stringify(data),
  })
  return JSON.parse(res.result as string)
}

// 下载文件
export async function downloadFile(url: string, savePath: string): Promise<string> {
  const res = await client.request(url, {
    method: http.RequestMethod.GET,
    expectDataType: http.HttpDataType.ARRAY_BUFFER,
  })
  const arrBuff = res.result as ArrayBuffer
  const fd = fs.openSync(savePath, fs.OpenMode.CREATE | fs.OpenMode.WRITE_ONLY)
  fs.writeSync(fd, new Uint8Array(arrBuff))
  fs.closeSync(fd)
  return savePath
}

// WebSocket
export function startWs(url: string) {
  const ws = websocket.createWebSocket()
  ws.on('open', () => {
    console.log('ws connected')
    ws.send('hello server')
  })
  ws.on('message', (msg) => console.log('ws message:', msg.data))
  ws.on('close', () => console.log('ws closed'))
  ws.on('error', (e) => console.error('ws error', e))
  ws.connect(url)
  return ws
}

// 网络可用性
export async function hasNetwork(): Promise<boolean> {
  try {
    const net = await connectivity.getDefaultNet()
    return !!net
  } catch {
    return false
  }
}

export function watchNetwork(fn: (up: boolean) => void) {
  connectivity.on('netAvailable', () => fn(true))
  connectivity.on('netLost', () => fn(false))
}

// 清理
export function dispose() {
  client.destroy()
}

这样一来,你的项目里只需要引入 NetUtils,就能随时发请求或监听网络状态。

场景应用

拉取首页数据(GET 请求)

比如一个电商应用,打开首页需要拉取商品列表:

ts 复制代码
import { getJson } from './NetUtils'

interface Item { id: number; name: string; price: number }

async function loadHomeData() {
  try {
    const items = await getJson<Item[]>('https://api.example.com/items')
    console.log('商品数量:', items.length)
  } catch (err) {
    console.error('加载失败:', err)
  }
}

这里我们通过 getJson 直接拿到了数组对象,不需要自己去拼接 JSON 解析逻辑。

提交订单(POST 请求)

在下单时,需要把购物车的数据提交到服务器:

ts 复制代码
import { postJson } from './NetUtils'

async function createOrder() {
  const order = { userId: 1, productId: 101, count: 2 }
  const res = await postJson<{ orderId: string }>('https://api.example.com/orders', order)
  console.log('下单成功,订单号:', res.orderId)
}

因为封装了 postJson,所以调用时只需要传对象即可,返回值会自动解析成目标类型。

实时聊天(WebSocket)

聊天功能通常需要长连接:

ts 复制代码
import { startWs } from './NetUtils'

function connectChat() {
  const ws = startWs('wss://echo.websocket.events')
  setTimeout(() => ws.send('你好,这是一条消息'), 2000)
}

这个例子用的是一个回声服务,适合测试。在真实项目里,你可以替换为后端的聊天服务器地址。

网络状态检测

有时候我们需要在用户断网时提示他们:

ts 复制代码
import { watchNetwork } from './NetUtils'

watchNetwork((up) => {
  if (up) {
    console.log('网络已恢复')
  } else {
    console.log('网络断开,请检查连接')
  }
})

这样用户在 WiFi/4G 切换、网络断开时,都能及时收到提示。

QA 环节

Q: HTTP 客户端需要每次都 createHttp() 吗?

A: 不需要,最好复用同一个实例,减少资源消耗。退出应用时再 destroy()

Q: HTTPS 自签名证书能用吗?

A: 默认只信任系统 CA,自签名需要额外配置,具体要看安全策略。

Q: 文件下载很大怎么办?

A: 建议分块下载,并在写入时加上进度条提示,可以通过响应头里的 content-length 来计算进度。

Q: WebSocket 断线了怎么办?

A: 可以在 on('close') 里尝试重连,或者给用户一个"重新连接"的按钮。

总结

在鸿蒙应用中访问和使用网络资源,其实就是四个关键点:

  1. 配好权限;
  2. HTTP 请求(GET/POST/下载);
  3. WebSocket 实时通信;
  4. 网络可用性检测。

我们把这些功能封装在一个工具模块里,就能在项目里直接调用,减少重复代码。结合几个常见的场景------商品列表加载、订单提交、聊天、断网提示,你会发现这些接口用起来非常直观。

如果你正在写一个需要联网的鸿蒙应用,可以把这里的 NetUtils.ets 拿过去直接用,然后根据业务需求再加上进度回调、错误处理和重试机制,就能跑在生产环境了。

相关推荐
GeniuswongAir26 分钟前
交叉编译.so到鸿蒙使用
华为·harmonyos
VVVVWeiYee1 小时前
TCP/UDP详解(一)
运维·网络·tcp/ip·udp·信息与通信
Xの哲學2 小时前
Linux PCI 子系统:工作原理与实现机制深度分析
linux·网络·算法·架构·边缘计算
keepDXRcuriosity2 小时前
ArkTS 语言全方位解析:鸿蒙生态开发新选择
华为·harmonyos·arkts·鸿蒙
whysqwhw2 小时前
鸿蒙图标快捷菜单
harmonyos
whysqwhw3 小时前
鸿蒙模块间资源引用
harmonyos
whysqwhw3 小时前
鸿蒙Flex与Row/Column对比
harmonyos
无级程序员3 小时前
kubernetes-dashboard使用http不登录
http·容器·kubernetes
weixin_449173654 小时前
WiFi有网络但是电脑连不上网是怎么回事?该怎么解决?
网络
熬夜苦读学习4 小时前
Reactor 反应堆模式
运维·服务器·网络·网络协议·http·智能路由器·php