OpenHarmony Fetch 网络请求实战:接口请求与数据解析全教程
应用开发离不开网络交互,从首页商品、资讯加载到登录提交,都需要调用后端接口。OpenHarmony 原生使用fetch实现 http/https 网络请求,无需额外引入三方库,支持 GET、POST、请求头配置、JSON 解析。本文讲解基础请求、参数传递、异常捕获,搭配真实模拟接口,结合前面 Preferences、ArkUI 组件完成网络数据列表展示实战。开发前置:配置网络权限 项目目录→ mo
·
一、前言
应用开发离不开网络交互,从首页商品、资讯加载到登录提交,都需要调用后端接口。OpenHarmony 原生使用fetch实现 http/https 网络请求,无需额外引入三方库,支持 GET、POST、请求头配置、JSON 解析。本文讲解基础请求、参数传递、异常捕获,搭配真实模拟接口,结合前面 Preferences、ArkUI 组件完成网络数据列表展示实战。
开发前置:配置网络权限 项目目录
src/main/module.json5→ module.requestPermissions 添加网络权限:
json
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
二、Fetch 基础语法说明
fetch 返回 Promise 异步对象,分为两步:
- fetch (url, options) 发起请求,返回 Response 响应对象
- response.json () 解析 json 格式数据
- GET:参数拼在 URL 末尾
- POST:参数放在 body 中,需配置请求头
Content-Type
三、GET 请求实战(无参 / 带参)
3.1 无参数 GET 获取接口数据
ets
@Entry
@Component
struct FetchGetDemo {
@State resText: string = ""
// GET请求
async requestGet() {
try {
// 公开测试JSON接口
let resp = await fetch("https://jsonplaceholder.typicode.com/posts/1")
let data = await resp.json()
this.resText = JSON.stringify(data, null, 2)
} catch (err) {
this.resText = "请求异常:" + JSON.stringify(err)
}
}
build() {
Column({ space: 15 }) {
Button("发起GET请求").onClick(() => this.requestGet())
Scroll() {
Text(this.resText).fontSize(14).padding(10)
}
.width("100%")
.layoutWeight(1)
}
.padding(20)
.height("100%")
}
}
3.2 GET 拼接请求参数
ets
async getWithParam() {
let id = 5
let url = `https://jsonplaceholder.typicode.com/posts/${id}`
let res = await fetch(url)
let result = await res.json()
console.info("携带参数数据:", result.title)
}
四、POST 请求(提交表单 JSON 参数)
POST 多用于登录、提交表单,请求体使用 JSON 格式,固定请求头:Content-Type: application/json
ets
async requestPost() {
let url = "https://jsonplaceholder.typicode.com/posts"
// 请求参数
let bodyData = {
title: "OpenHarmony测试文章",
body: "鸿蒙fetch网络开发",
userId: 1
}
let options: RequestInit = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(bodyData)
}
try {
let resp = await fetch(url, options)
let data = await resp.json()
console.info("POST返回数据:", data)
} catch (e) {
console.error("请求失败", e)
}
}
五、封装通用网络请求工具类
项目中统一封装请求,统一处理异常、请求头,便于后期维护:
ets
class HttpUtil {
// 通用GET
static async get(url: string) {
let res = await fetch(url)
if (!res.ok) throw new Error("接口异常:" + res.status)
return await res.json()
}
// 通用POST
static async post(url: string, data: Object) {
let opt: RequestInit = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
}
let res = await fetch(url, opt)
if (!res.ok) throw new Error("接口异常:" + res.status)
return await res.json()
}
}
六、综合实战:网络数据渲染 List 列表(融合懒加载 LazyForEach)
业务:请求接口批量获取文章数据,通过 LazyForEach 渲染列表,下拉刷新重新请求接口。
ets
// 懒加载数据源
class ArticleDataSource implements ICollectionData {
private list: Array<Object> = []
setData(arr: Object[]) {
this.list = arr
}
getTotalCount(): number { return this.list.length }
getData(index: number): Object { return this.list[index] }
setDataChangeListener(listener: DataChangeListener): void {}
}
@Entry
@Component
struct NetListPage {
@State isRefresh: boolean = false
dataSource: ArticleDataSource = new ArticleDataSource()
// 请求接口刷新数据
async loadArticle() {
this.isRefresh = true
try {
let list = await HttpUtil.get("https://jsonplaceholder.typicode.com/posts?_limit=20")
this.dataSource.setData(list)
} catch (err) {
console.error("数据加载失败", err)
} finally {
this.isRefresh = false
}
}
aboutToAppear() {
this.loadArticle()
}
build() {
Column() {
Text("资讯列表").fontSize(22).fontWeight(Font.Bold).padding(15)
List() {
LazyForEach(this.dataSource, (item: any) => {
ListItem() {
Column({ space:6 }) {
Text(item.title).fontSize(16).fontWeight(FontWeight.Bold)
Text(item.body).fontSize(14).fontColor("#666")
}
.width("100%")
.padding(12)
.backgroundColor("#fff")
.borderRadius(8)
.margin({ bottom:8 })
}
})
}
.width("100%")
.layoutWeight(1)
.refresh({refreshing: this.isRefresh})
.onRefresh(()=>this.loadArticle())
}
.width("100%")
.backgroundColor("#F5F5F5")
}
}
七、拓展实战:登录页网络提交 + 本地存储(融合 Preferences)
点击登录发起 POST 请求,登录成功后使用 Preferences 保存登录状态。
ets
import preferences from '@ohos.data.preferences'
import common from '@ohos.app.ability.common'
@Entry
@Component
struct NetLoginPage {
@State account: string = ""
@State pwd: string = ""
context = getContext(this) as common.UIAbilityContext
// 登录请求
async doLogin() {
let loginParam = {
username: this.account,
password: this.pwd
}
try {
// 模拟登录接口
let res = await HttpUtil.post("https://jsonplaceholder.typicode.com/users", loginParam)
// 登录成功,持久化保存登录标识
let pre = await preferences.getPreferences(this.context, "user_login")
await pre.put("isLogin", true)
await pre.put("userName", this.account)
await pre.flush()
AlertDialog.show({title:"提示",message:"登录成功!"})
} catch (err) {
AlertDialog.show({title:"提示",message:"登录失败"})
}
}
build() {
Column({ space:20 }) {
TextInput({placeholder:"账号"}).width("90%").onChange(v=>this.account=v)
TextInput({placeholder:"密码"}).type(InputType.Password).width("90%").onChange(v=>this.pwd=v)
Button("登录").width("90%").backgroundColor("#007DFF").onClick(()=>this.doLogin())
}
.width("100%").height("100%").justifyContent(FlexAlign.Center).padding(20)
}
}
八、开发规范与踩坑总结
- 权限必开:忘记配置 INTERNET 会直接请求报错;
- 异常捕获:所有网络请求必须套
try/catch,避免断网闪退; - 数据格式:POST 传 JSON 必须配置 Header,否则后端无法解析参数;
- 频繁请求优化:页面销毁时取消无用请求,避免内存浪费;
- HTTPS 优先:OpenHarmony 默认支持 https,http 部分设备需要额外配置白名单。
更多推荐



所有评论(0)