系列:HarmonyOS 开发入门 · 09

网络请求的 API 本身不复杂,真正容易出问题的是:权限没配、返回值类型没处理、请求对象没销毁、业务层到处重复写一坨 HTTP 代码。

这篇先把最基础的 GET / POST 跑通,再讲我会怎么收口。

1. 声明网络权限

先在 module.json5 里声明网络权限:

"requestPermissions": [
  {
    "name": "ohos.permission.INTERNET"
  }
]

INTERNET 属于常用系统授权权限,不是那种每次弹窗让用户点允许的权限。

2. 导入 HTTP 模块

现在 Kit 化导入建议写:

import { http } from '@kit.NetworkKit'
import { BusinessError } from '@kit.BasicServicesKit'

3. 一个 GET 请求

async function getUser(): Promise<void> {
  const request = http.createHttp()

  try {
    const response = await request.request(
      'https://example.com/api/user/1001',
      {
        method: http.RequestMethod.GET,
        connectTimeout: 10000,
        readTimeout: 10000
      }
    )

    console.info(`status = ${response.responseCode}`)
    console.info(`result = ${response.result}`)
  } catch (error) {
    const err = error as BusinessError
    console.error(`request failed: ${err.code}, ${err.message}`)
  } finally {
    request.destroy()
  }
}

finally 里销毁 HttpRequest 是个好习惯。

4. POST JSON

async function login(account: string, password: string): Promise<void> {
  const request = http.createHttp()

  try {
    const response = await request.request(
      'https://example.com/api/login',
      {
        method: http.RequestMethod.POST,
        header: {
          'Content-Type': 'application/json'
        },
        extraData: JSON.stringify({
          account: account,
          password: password
        }),
        connectTimeout: 10000,
        readTimeout: 10000
      }
    )

    if (response.responseCode !== 200) {
      console.error(`http error: ${response.responseCode}`)
      return
    }

    const raw = response.result as string
    console.info(raw)
  } catch (error) {
    const err = error as BusinessError
    console.error(`${err.code}: ${err.message}`)
  } finally {
    request.destroy()
  }
}

5. JSON 解析别散落在页面里

比如返回:

{
  "code": 0,
  "data": {
    "id": 1001,
    "name": "Jack"
  }
}

可以先定义模型:

interface User {
  id: number
  name: string
}

interface ApiResponse<T> {
  code: number
  data: T
}

JSON 的边界解析最好集中在网络层,不要每个页面都自己 JSON.parse()

页面应该拿到接近业务语义的结果,而不是处理 HTTP 细节。

6. 页面里最不该出现的写法

我不喜欢这种结构:

Button('加载').onClick(async () => {
  const request = http.createHttp()
  // 下面 50 行网络逻辑
})

按钮只应该表达:用户点了以后要做什么。

例如:

Button('加载').onClick(() => {
  this.loadUser()
})

HTTP 细节放 Service 或 Repository。

7. 最小封装思路

export class HttpClient {
  static async get(url: string): Promise<string> {
    const request = http.createHttp()
    try {
      const response = await request.request(url, {
        method: http.RequestMethod.GET,
        connectTimeout: 10000,
        readTimeout: 10000
      })

      if (response.responseCode < 200 || response.responseCode >= 300) {
        throw new Error(`HTTP ${response.responseCode}`)
      }

      return response.result as string
    } finally {
      request.destroy()
    }
  }
}

真正项目里还会继续加:

  • BaseURL;
  • Token;
  • 公共 Header;
  • 日志;
  • 错误码映射;
  • 重试;
  • 取消请求。

但入门阶段先别封装过头。

8. HTTPS 和明文 HTTP

正式项目尽量使用 HTTPS。

如果请求地址是内网或明文 HTTP,还需要关注网络安全配置和系统限制,不要为了测试临时改了一堆全局安全配置最后忘记恢复。

总结

HTTP 入门记住:

  1. 配网络权限;
  2. http.createHttp()
  3. request()
  4. 处理状态码和类型;
  5. destroy()
  6. 别把网络逻辑写满页面。

下一篇讲本地存储。到底什么时候用 Preferences、什么时候上关系型数据库,是很多小项目一开始就选错的地方。

Logo

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

更多推荐