当前位置: 首页 > news >正文

网络请求基础:使用http模块发起GET/POST请求(12)

在鸿蒙(HarmonyOS)ArkTS 开发中,网络请求是应用与服务器进行数据交互的核心能力。系统提供了@ohos.net.http(或新版@kit.NetworkKit)模块来支持 GET、POST 等常见的 HTTP 方法。

以下是使用 HTTP 模块发起网络请求的完整指南:

一、 前置准备:配置网络权限

在使用任何网络请求功能之前,必须在应用的配置文件module.json5中声明网络访问权限:

{ "module": { "reqPermissions": [ { "name": "ohos.permission.INTERNET" } ] } }

二、 核心 API 设计哲学

需要特别注意的是,鸿蒙的 HTTP API 设计中不存在独立的get()post()方法。所有的 HTTP 请求(GET/POST/PUT/DELETE等)均通过统一的request()方法实现,开发者需要在配置参数中通过method字段来指定具体的请求类型。

一个标准的请求生命周期包括:创建对象 (createHttp) -> 发起请求 (request) -> 处理响应 -> 销毁对象 (destroy)。

三、 GET 请求实战(获取数据)

GET 请求通常用于从服务器拉取列表或详情数据。以下是一个结合 UI 状态更新的完整示例

entry/src/main/module.json5

{ "module": { "name": "entry", // 【新增】模块名称,通常与文件夹同名 "type": "entry", // 【新增】模块类型,主模块必须为 "entry" "description": "$string:module_desc", "mainElement": "EntryAbility", "deviceTypes": [ "phone", "tablet" ], "deliveryWithInstall": true, "pages": "$profile:main_pages", "abilities": [ { "name": "EntryAbility", "srcEntry": "./ets/entryability/EntryAbility.ets", "description": "$string:EntryAbility_desc", "icon": "$media:layered_image", "label": "$string:EntryAbility_label", "startWindowIcon": "$media:startIcon", "startWindowBackground": "$color:start_window_background", "exported": true, "skills": [ { "entities": ["entity.system.home"], "actions": ["action.system.home"] } ] } ], "requestPermissions": [ // 【修正】将 reqPermissions 改为 requestPermissions { "name": "ohos.permission.INTERNET" } ] } }
// src/main/ets/pages/GetExample.ets import http from '@ohos.net.http'; @Entry @Component struct GetExample { @State data: string = '点击按钮开始请求'; @State isLoading: boolean = false; // 控制加载动画的状态 async fetchData() { this.isLoading = true; // 开始请求,显示加载状态 const httpRequest = http.createHttp(); // 1. 创建请求对象 try { const response = await httpRequest.request( 'https://jsonplaceholder.typicode.com/posts/1', // 测试接口地址 { method: http.RequestMethod.GET, // 2. 指定为 GET 方法 header: { 'Content-Type': 'application/json' }, connectTimeout: 60000, // 连接超时时间 (ms) readTimeout: 60000 // 读取超时时间 (ms) } ); // 3. 处理响应数据 if (response.responseCode === 200) { this.data = JSON.stringify(JSON.parse(response.result as string), null, 2); } else { this.data = `请求失败: ${response.responseCode}`; } } catch (error) { // 4. 捕获并展示异常信息 this.data = `请求异常: ${(error as Error).message}`; } finally { httpRequest.destroy(); // 5. 【关键】请求完毕后必须销毁,防止内存泄漏 this.isLoading = false; // 结束请求,隐藏加载状态 } } build() { Column({ space: 20 }) { Button('发起 GET 请求') .onClick(() => this.fetchData()) .width('80%') .height(48) // 根据加载状态显示不同内容 if (this.isLoading) { Progress({ value: 50, total: 100, type: ProgressType.Ring }) .width(40) .height(40) } else { Text(this.data) .fontSize(14) .padding(20) .width('90%') .wordBreak(WordBreak.BREAK_ALL) // 允许长文本自动换行 } } .width('100%') .height('100%') .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center) } }
// src/main/resources/base/profile/main_pages.json { "src": [ "pages/Index", "pages/GetExample" ] }

四、 POST 请求实战(提交数据)

POST 请求常用于表单提交或向服务器推送数据。与 GET 不同,POST 的数据需要放在请求体中,通过extraData字段传递:

async submitData() { const httpRequest = http.createHttp(); const requestData = { title: 'foo', body: 'bar', userId: 1 }; try { const response = await httpRequest.request( 'https://jsonplaceholder.typicode.com/posts', { method: http.RequestMethod.POST, // 指定为 POST 方法 header: { 'Content-Type': 'application/json' }, extraData: JSON.stringify(requestData) // 将对象序列化为 JSON 字符串放入请求体 } ); if (response.responseCode === 201) { console.info('创建成功:', response.result); } } catch (error) { console.error('提交异常:', error); } finally { httpRequest.destroy(); } }

五、 进阶封装:打造通用请求工具类

在实际工程中,为了避免在每个页面重复编写createHttpdestroy逻辑,建议将其封装为通用的 Promise 函数:

import http from '@ohos.net.http'; // 通用请求方法 function httpRequest(url: string, method: http.RequestMethod, params?: string): Promise<string> { let req = http.createHttp(); return req.request(url, { method: method, header: { 'Content-Type': 'application/json' }, connectTimeout: 10000, readTimeout: 10000, extraData: params }).then((value: http.HttpResponse) => { req.destroy(); // 成功时销毁 if (value.responseCode === 200) return value.result as string; throw new Error(`Server Error: ${value.responseCode}`); }).catch((err: Error) => { req.destroy(); // 异常时也要确保销毁 throw err; }); } // 快捷调用方法 export function get(url: string) { return httpRequest(url, http.RequestMethod.GET); } export function post(url: string, data: object) { return httpRequest(url, http.RequestMethod.POST, JSON.stringify(data)); }

高级进阶:拦截器与全局状态管理

在大型应用中,通常需要处理统一的 Token 注入、错误码拦截以及全局加载状态。结合@State管理和拦截器模式,可以实现更优雅的网络层封装。

1. 添加请求拦截器

在工具类中增加拦截器逻辑,用于处理鉴权或日志:

// 定义拦截器接口 interface Interceptor { onRequest(config: http.HttpRequestOptions): http.HttpRequestOptions; onResponse(response: http.HttpResponse): http.HttpResponse; onError(error: Error): void; } // 在请求工具中集成拦截器 class HttpClient { private interceptors: Interceptor[] = []; addInterceptor(interceptor: Interceptor) { this.interceptors.push(interceptor); } async request(url: string, options: http.HttpRequestOptions) { // 执行请求拦截 this.interceptors.forEach(interceptor => { options = interceptor.onRequest(options); }); const httpRequest = http.createHttp(); try { const response = await httpRequest.request(url, options); // 执行响应拦截 this.interceptors.forEach(interceptor => { interceptor.onResponse(response); }); return response; } catch (error) { this.interceptors.forEach(interceptor => { interceptor.onError(error as Error); }); throw error; } finally { httpRequest.destroy(); } } }
2. 全局加载状态管理

结合@State和拦截器,可以实现全局的加载动画控制,避免在每个页面重复编写加载逻辑:

// 全局状态管理类 class LoadingManager { @State static isLoading: boolean = false; private static requestCount: number = 0; static show() { if (this.requestCount === 0) { this.isLoading = true; } this.requestCount++; } static hide() { this.requestCount--; if (this.requestCount <= 0) { this.requestCount = 0; this.isLoading = false; } } } // 在拦截器中使用 const loadingInterceptor: Interceptor = { onRequest(config) { LoadingManager.show(); return config; }, onResponse(response) { LoadingManager.hide(); return response; }, onError(error) { LoadingManager.hide(); console.error('Global error handler:', error); } };
3. 使用示例
// 在页面中使用 @Entry @Component struct AdvancedPage { @State data: string = ''; async fetchData() { try { const response = await get('https://jsonplaceholder.typicode.com/posts/1'); this.data = response; } catch (error) { // 错误已被全局拦截器处理 } } build() { Column() { // 页面内容 Button('加载数据').onClick(() => this.fetchData()) // 全局加载遮罩 if (LoadingManager.isLoading) { LoadingComponent() } } } }

避坑指南与最佳实践

  • 资源释放:每一个httpRequest对象对应一个独立的任务且不可复用,最多只能创建 100 个。务必在finally块或.catch()中调用destroy()释放资源。
  • 大小限制:默认的request()接口仅支持接收 5MB 以内的数据。如果需要下载大文件或视频流,请使用requestInStream()配合dataReceive事件监听。
  • 异步处理:推荐使用async/await语法代替传统的 Callback 回调,这能让你的网络请求代码具备更好的可读性和错误捕获能力。
  • 拦截器模式:对于复杂的业务应用,建议引入拦截器模式来处理统一的鉴权、日志和错误处理,保持业务代码的纯净。
http://www.zskr.cn/news/1499456.html

相关文章:

  • 全固态电池技术路线解析,硫化物、氧化物、聚合物谁主沉浮?
  • 深圳卡地亚回收避坑要点|先查资质、再看报价、最后结算 - 奢侈品回收测评
  • 【Azure AI Search】 searchMode=any 和 searchMode=all 有什么区别?
  • SQL/NoSQL数据库为何成为TVA的记忆系统(8)
  • 模型训练为什么一上 Pipeline Parallel 就开始显存更稳却气泡时间更难压:从 Stage Balance 到 Bubble Budget 的工程实战
  • 《多语言高并发巅峰对决:Python vs Java vs C++ 10万级QPS架构决策完全指南》第6章 序列化与协议瓶颈:JSON/Protobuf/Thrift/MessagePack在高压下的
  • 2026武汉名表回收实测——高端腕表变现避坑干货指南 - 奢侈品回收测评
  • 石材安装后不满意能退吗?消费者权益保护全解析(2026版) - 宁波融诚石业
  • 2026网盘隐私大测评!哪家文件加密最靠谱?高安全网盘横向盘点
  • 东芝原色RGB Mini LED(Evo):四色架构重构显示边界
  • 个人总结 docker搭建家庭媒体库Jellyfin
  • 石材色差是正常的吗?国家标准+验收红线全知道(2026版) - 宁波融诚石业
  • 宁波梅雨季装修石材防护专题:6-9月施工注意事项(2026版) - 宁波融诚石业
  • HTML5语义化与无障碍实践:构建面向未来的Web基石
  • 别再为乱码头疼了!SOLIDWORKS工程图转DWG字体设置保姆级教程(附drawfontmap.txt修改指南)
  • 警惕 “高价回收” 幌子:昆明包包回收真实利润与报价底线 - 奢侈品回收评测
  • 图片批量翻译工具测评:功能、价格与适用场景分析
  • Word公式排版救星:MathType 7.4.8安装避坑与右编号公式实战指南
  • 警惕“拿着 AI 找场景”:伪需求下的 Agent 泡沫
  • 《代码随想录》刷题打卡day11:二叉树part01
  • 宁波10个高端楼盘石材装修实景案例合集(2026版) - 宁波融诚石业
  • 告别鼠标手!Kicad 6.0 原理图与PCB设计最全快捷键清单(附PDF速查表)
  • Apollo配置中心踩坑记:从IDE变量到Server.properties,优先级与缓存那些事儿
  • Spring AI实战:快速集成阿里通义千问
  • 助睿Max数据大屏实战(进阶篇):浏览器用户画像大屏的数据接入与交互全解析
  • 别再死记硬背了!用STM32CubeMX+FreeModbus库,5分钟搞定你的第一个Modbus从机
  • 2026年 除漆剂/除臭剂/絮凝剂/消泡剂厂家推荐榜:源头工艺与环保高效除味消泡实力品牌解析 - 品牌发掘
  • dubbo和oppenFeign是如何找到正确的url请求地址的
  • 2026 消费电子异形磁铁赛道 多家源头厂商技术能力多维对比 - 变量人生001
  • 2026 成都迪奥回收最新行情,经典款与新款二手流通价差解析 - 奢侈品回收评测