鸿蒙应用网络开发实战: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 拿过去直接用,然后根据业务需求再加上进度回调、错误处理和重试机制,就能跑在生产环境了。

相关推荐
zhikouai4 分钟前
把外部助手接进聊天软件的架构分层与参数配置
服务器·网络·php
huainingning8 分钟前
锐捷10.X路由器版本升级不生效问题排查
运维·网络·智能路由器
用户86194177207412 小时前
uni-app 的蓝牙 API 在鸿蒙上不生效?我写了个兼容层,让老代码零改动跑起来
harmonyos
HarmonyOS_SDK4 小时前
【HarmonyOS SDK Skills】挂载 Agent Skill,轻松跑通鸿蒙应用广告变现
harmonyos
QZ166560951594 小时前
政务泛监测体系能力排行:AI 重塑监测边界,治理的颗粒度革命
网络·人工智能·安全·网络安全·政务
叼烟扛炮4 小时前
Linux 学习笔记(五十八):IO 多路复用封神——epoll 底层原理揭秘
linux·运维·服务器·网络·笔记·学习·php
叼烟扛炮4 小时前
Linux 学习笔记(五十一):数据链路层与 ARP 协议——局域网寻址与黑客骗局
linux·网络·网络协议·php·tcpdump
闫东阳LordGalaxy4 小时前
给小艺装上数学能力:数易 App 接入智能体 FunctionComponent 与 A2A 双通路实战
harmonyos
星恒随风5 小时前
Linux网络编程:彻底理解IO多路复用select!从fd_set位图、读写就绪到手写TCP多客户端字典服务器
linux·服务器·网络
Dream-Y.ocean5 小时前
鸿蒙PC平台逻控 PLC 编辑器适配实战:基于 Electron 壳方案的纯 JavaScript 梯形图编程与仿真引擎开发
javascript·编辑器·harmonyos