鸿蒙新特性:@ohos.net.http 网络请求实验室实战 —— GET/POST/PUT/DELETE 一站式调试
引言
网络请求是移动应用中最基础也最频繁的操作之一。无论是获取服务端数据、提交表单、上传文件还是调用第三方 API,都离不开 HTTP 客户端。HarmonyOS NEXT 通过 @ohos.net.http 模块为开发者提供了一套完整的 HTTP 客户端能力,覆盖从创建请求实例到处理响应结果的全生命周期。
@ohos.net.http 属于 @kit.NetworkKit,与 Android 的 HttpURLConnection 和 iOS 的 URLSession 定位类似,但 API 设计更加简洁直观。它的核心流程可以概括为三步:创建实例 → 发起请求 → 销毁实例。所有请求通过 Promise 异步返回,天然支持链式调用和 async/await 语法。
本文将深入讲解 @ohos.net.http 的 API 体系、请求构建、响应处理、超时配置和错误处理策略,并构建一个"网络请求实验室"Demo,让你在一个页面中完整体验 GET、POST、PUT、DELETE 四种常用方法的请求构建、参数配置和响应展示。
一、API 架构:以 HttpRequest 为核心的三步模式
1.1 核心设计理念
@ohos.net.http 的 API 设计遵循"创建 - 使用 - 销毁"的生命周期模式:
- 创建:通过
createHttp()获取一个HttpRequest实例 - 使用:通过
request(url, options)发送请求并获取HttpResponse - 销毁:通过
destroy()释放底层资源
这种设计与 Java 的 HttpURLConnection 的 openConnection() → connect() → disconnect() 模式一脉相承,但通过 Promise 封装消除了回调地狱。
import http from '@ohos.net.http';
// 三步标准模式
const httpReq = http.createHttp();
httpReq.request('https://api.example.com/data', {
method: http.RequestMethod.GET,
expectDataType: http.HttpDataType.STRING,
connectTimeout: 10000,
readTimeout: 10000
}).then((resp) => {
console.log('状态码:', resp.responseCode);
console.log('响应体:', resp.result);
}).catch((e: Error) => {
console.error('请求失败:', e.message);
}).finally(() => {
httpReq.destroy(); // 必须销毁
});
1.2 HttpRequest —— 请求任务实例
createHttp() 返回的 HttpRequest 对象代表一个 HTTP 任务实例。每个实例维护自己的连接池和配置,应当在使用完毕后调用 destroy() 销毁。
HttpRequest 的核心方法:
| 方法 | 说明 |
|---|---|
request(url, options?) |
发起 HTTP 请求,返回 Promise<HttpResponse> |
destroy() |
销毁实例,释放连接资源 |
on('headersReceive', callback) |
监听响应头接收事件 |
off('headersReceive', callback?) |
取消监听响应头事件 |
1.3 HttpRequestOptions —— 请求配置
HttpRequestOptions 是请求配置的核心数据结构:
interface HttpRequestOptions {
method?: RequestMethod; // 请求方法,默认 GET
header?: Object; // 请求头,键值对
extraData?: string | ArrayBuffer; // 请求体(POST/PUT 使用)
expectDataType?: HttpDataType; // 期望的响应数据类型
connectTimeout?: number; // 连接超时(ms),默认 60000
readTimeout?: number; // 读取超时(ms),默认 60000
usingProtocol?: HttpProtocol; // 使用的协议(HTTP/1.1 或 HTTP/2)
usingProxy?: boolean | Object; // 是否使用代理
caPath?: string; // CA 证书路径(HTTPS 双向认证)
clientCert?: ClientCert; // 客户端证书
}
在我们的 Demo 中,最小配置只需要 method 和 expectDataType:
const options: http.HttpRequestOptions = {
method: http.RequestMethod.GET,
header: { 'Content-Type': 'application/json' },
expectDataType: http.HttpDataType.STRING,
connectTimeout: 10000,
readTimeout: 10000
};
1.4 RequestMethod —— 请求方法枚举
RequestMethod 枚举定义了 HTTP 方法:
| 枚举值 | 说明 |
|---|---|
| GET | 获取资源 |
| POST | 创建资源 |
| PUT | 更新资源(全量) |
| DELETE | 删除资源 |
| HEAD | 获取响应头(无响应体) |
| OPTIONS | 查询服务器支持的方法 |
| PATCH | 更新资源(部分) |
| CONNECT | 建立隧道连接 |
| TRACE | 回显请求用于诊断 |
最常用的是 GET、POST、PUT、DELETE,也是 Demo 中覆盖的四种方法。
1.5 HttpDataType —— 响应数据类型
HttpDataType 枚举控制 HttpResponse.result 的类型:
| 枚举值 | 数值 | result 类型 | 适用场景 |
|---|---|---|---|
| STRING | 0 | string |
JSON API 响应、HTML、纯文本 |
| ARRAY_BUFFER | 1 | ArrayBuffer |
二进制数据(图片、文件下载) |
| OBJECT | 2 | Object |
框架自动 JSON.parse 后的对象 |
大多数 API 调用场景使用 STRING 类型,这样可以直接拿到 JSON 字符串后用 JSON.parse() 解析。
1.6 HttpResponse —— 响应对象
HttpResponse 包含了完整的响应信息:
interface HttpResponse {
result: string | ArrayBuffer | Object; // 响应体
responseCode: number; // HTTP 状态码(200, 404, 500 等)
header: Object; // 响应头键值对
cookies: string; // Cookie 字符串
}
处理响应时的常用模式:
httpReq.request(url, options).then((resp: http.HttpResponse) => {
if (resp.responseCode >= 200 && resp.responseCode < 300) {
// 2xx 成功
const data = JSON.parse(resp.result as string);
} else if (resp.responseCode === 404) {
// 资源不存在
} else {
// 其他状态码
}
});
二、核心 API 详解
2.1 createHttp() —— 创建请求实例
function createHttp(): HttpRequest;
createHttp() 是工厂方法,每次调用返回一个新的 HttpRequest 实例。每个实例独立管理自己的连接和超时配置。不能重复使用已经 destroy() 的实例。
2.2 request() —— 发起请求
function request(url: string, options?: HttpRequestOptions): Promise<HttpResponse>;
request() 是异步操作,返回 Promise。请求配置通过 options 参数传入:
- method:默认
GET,可选POST、PUT、DELETE等 - header:自定义请求头。
Content-Type是最常用的,JSON 请求设为application/json - extraData:请求体,仅 POST/PUT 等带 Body 的方法使用。接受
string或ArrayBuffer类型。在 ArkTS 严格模式下,普通 JS 对象必须先用JSON.stringify()转为字符串 - connectTimeout:TCP 连接超时,单位毫秒,默认 60000
- readTimeout:数据读取超时,单位毫秒,默认 60000
注意:ArkTS 严格模式下,extraData 接受 string 或 ArrayBuffer 类型,不能直接传递普通对象。发送 JSON 数据时需要先 JSON.stringify():
// 正确:先序列化
options.extraData = JSON.stringify({ title: 'foo', body: 'bar', userId: 1 });
// 错误:ArkTS 严格模式下类型不兼容
options.extraData = { title: 'foo', body: 'bar', userId: 1 }; // 编译错误
2.3 destroy() —— 销毁实例
function destroy(): void;
每个 HttpRequest 实例在使用完毕后必须调用 destroy() 释放连接和内存资源。这是一个同步方法,不会抛异常。最佳实践是在 Promise 的 then 和 catch 分支中都调用 destroy(),或者在 finally 中统一处理:
httpReq.request(url, options).then((resp) => {
// 处理响应
httpReq.destroy();
}).catch((e) => {
// 处理错误
httpReq.destroy();
});


三、权限配置
使用 @ohos.net.http 需要声明 ohos.permission.INTERNET 权限。这是一项 normal 级别权限,声明即授权,无需用户手动确认。
在 module.json5 中配置:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET",
"reason": "$string:internet_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
]
}
}
注意:如果使用 HTTPS 双向认证,还需要配置 ohos.permission.INTERNET 外加客户端证书;如果使用了代理功能,可能需要额外网络权限。
四、实战 Demo:网络请求实验室
本节构建一个完整的网络请求调试工具,在一个页面中覆盖 GET/POST/PUT/DELETE 请求构建、响应查看和请求历史追踪。
4.1 页面设计
页面分为五个功能区域:
- 快捷请求:三个预设按钮(GET /posts/1、POST /posts、PUT /posts/1),点击即发,方便快速体验不同 HTTP 方法
- 请求构建器:方法选择器(GET/POST/PUT/DELETE)+ URL 输入框 + 条件显示的请求体编辑器(仅 POST/PUT 时显示)+ 发送按钮
- 响应结果面板:状态码显示(2xx 绿色 / 4xx+ 红色)+ 滚动响应体展示
- 请求历史:展示最近 20 条请求记录,含方法标签、URL、时间戳、耗时、状态码
- 操作日志:记录所有操作的实时日志流,区分系统信息、成功和错误
4.2 核心实现
发送请求 —— 核心逻辑封装在 sendRequest() 方法中:
private sendRequest(): void {
if (this.urlInput.trim() === '') {
this.addLog('请输入 URL', 'error');
return;
}
const method = this.methods[this.methodIndex];
this.loading = true;
const startTime = Date.now();
const httpReq = http.createHttp();
const options: http.HttpRequestOptions = {
method: method as http.RequestMethod,
header: { 'Content-Type': 'application/json' },
expectDataType: http.HttpDataType.STRING,
connectTimeout: 10000,
readTimeout: 10000
};
if (method === 'POST' || method === 'PUT') {
if (this.bodyInput.trim() !== '') {
options.extraData = this.bodyInput;
} else {
options.extraData = JSON.stringify({ title: 'test', body: 'hello', userId: 1 });
}
}
httpReq.request(this.urlInput, options).then((resp: http.HttpResponse) => {
const elapsed = Date.now() - startTime;
this.loading = false;
this.statusCode = resp.responseCode.toString();
this.statusColor = resp.responseCode >= 200 && resp.responseCode < 300 ?
'#10B981' : '#EF4444';
let body = '';
if (typeof resp.result === 'string') {
body = resp.result;
} else if (resp.result instanceof ArrayBuffer) {
body = '[ArrayBuffer ' + resp.result.byteLength + ' bytes]';
} else {
body = '[Object]';
}
if (body.length > 2000) {
body = body.substring(0, 2000) + '\n... (截断)';
}
this.responseBody = body;
// 记录历史
this.addToHistory(method, elapsed, resp.responseCode);
this.addLog(method + ' ' + this.urlInput + ' → ' + resp.responseCode +
' (' + elapsed + 'ms)', 'success');
httpReq.destroy();
}).catch((e: Error) => {
this.loading = false;
this.statusCode = '错误';
this.statusColor = '#EF4444';
this.responseBody = '请求失败: ' + e.message;
this.addLog(method + ' 失败: ' + e.message, 'error');
httpReq.destroy();
});
}
关键设计点:
- 使用
Date.now()计算请求耗时,对性能分析很有价值 - 响应体超过 2000 字符时截断,避免 UI 渲染性能问题
- 对
ArrayBuffer和Object类型做兼容处理 - 无论成功还是失败都调用
destroy()
响应体类型处理 —— HttpResponse.result 的类型取决于 expectDataType 配置:
let body = '';
if (typeof resp.result === 'string') {
body = resp.result; // STRING 类型
} else if (resp.result instanceof ArrayBuffer) {
body = '[ArrayBuffer ' + resp.result.byteLength + ' bytes]'; // ARRAY_BUFFER
} else {
body = '[Object]'; // OBJECT 类型
}
快捷演示 —— 预设请求一键发送:
private sendDemo(code: number): void {
if (code === 1) {
this.urlInput = 'https://jsonplaceholder.typicode.com/posts/1';
this.methodIndex = 0; // GET
this.bodyInput = '';
this.sendRequest();
} else if (code === 2) {
this.urlInput = 'https://jsonplaceholder.typicode.com/posts';
this.methodIndex = 1; // POST
this.bodyInput = JSON.stringify({ title: 'foo', body: 'bar', userId: 1 });
this.sendRequest();
} else if (code === 3) {
this.urlInput = 'https://jsonplaceholder.typicode.com/posts/1';
this.methodIndex = 2; // PUT
this.bodyInput = JSON.stringify({ id: 1, title: 'updated', body: 'updated', userId: 1 });
this.sendRequest();
}
}
这里使用了 jsonplaceholder.typicode.com 这个公开的 REST API 测试服务,它提供标准的 JSON 响应,非常适合开发调试。
4.3 Demo 测试接口说明
Demo 使用的 JSONPlaceholder 接口:
| 方法 | 端点 | 说明 | 预期响应 |
|---|---|---|---|
| GET | /posts/1 | 获取单篇文章 | 200,返回文章 JSON |
| POST | /posts | 创建新文章 | 201,返回创建后的文章(含 id: 101) |
| PUT | /posts/1 | 更新文章 | 200,返回更新后的文章 |
这些接口是只读模拟(POST/PUT 不会真正修改数据),但返回的 HTTP 状态码和 JSON 结构与真实 API 完全一致,适合开发测试。
4.4 交互方式
Demo 提供四个核心交互点:
- 快捷请求按钮:免配置,点击即发送预设的 GET/POST/PUT 请求,适合快速体验不同 HTTP 方法的行为差异
- 请求构建器:允许自定义 URL、选择 HTTP 方法、编辑 JSON 请求体(POST/PUT 时显示),完整模拟 API 调试工作流
- 响应面板:实时显示 HTTP 状态码(颜色编码:2xx 绿色、4xx+ 红色)和响应体,支持长文本滚动查看
- 请求历史:自动记录最近 20 条请求,每条显示方法标签(彩色区分)、URL、时间戳、耗时和状态码,便于对比分析
五、错误处理策略
5.1 常见错误码
@ohos.net.http 的 request() 在失败时通过 Promise reject 返回错误,常见错误包括:
| 场景 | 错误信息 | 排查方向 |
|---|---|---|
| URL 格式错误 | Parameter error | 检查 URL 是否以 http:// 或 https:// 开头 |
| 连接超时 | Connect timeout | 检查网络连接和 connectTimeout 设置 |
| 读取超时 | Read timeout | 服务端响应过慢,调大 readTimeout |
| DNS 解析失败 | Cannot resolve host | 检查域名是否正确,DNS 是否可用 |
| SSL 证书错误 | SSL handshake failed | 检查 HTTPS 证书是否有效 |
| 无网络权限 | Permission denied | 检查 module.json5 中的 INTERNET 权限配置 |
| 实例已销毁 | Instance destroyed | 不能再使用已调用 destroy() 的实例 |
5.2 超时配置建议
// 不同场景的超时配置建议
const fastOptions: http.HttpRequestOptions = {
connectTimeout: 5000, // 快速失败,适合健康检查
readTimeout: 5000
};
const normalOptions: http.HttpRequestOptions = {
connectTimeout: 10000, // 标准 API 调用
readTimeout: 15000
};
const uploadOptions: http.HttpRequestOptions = {
connectTimeout: 30000, // 大文件上传 / 下载
readTimeout: 60000
};
六、ArkTS 严格模式注意事项
6.1 跨模块类型转换
在 ArkTS 严格模式下,http.RequestMethod 是枚举类型,直接赋值给 options.method 没有问题。但如果 method 来自字符串变量(如 Demo 中的 this.methods[this.methodIndex]),需要使用 as http.RequestMethod 进行类型断言。
6.2 extraData 类型限制
ArkTS 严格模式下,extraData 只接受 string 或 ArrayBuffer,不能传入普通 JS 对象。发送 JSON 时必须用 JSON.stringify() 转换:
// 正确
options.extraData = JSON.stringify({ name: 'test' });
// 编译错误
options.extraData = { name: 'test' };
6.3 result 类型检查
由于 HttpResponse.result 是联合类型(string | ArrayBuffer | Object),使用前需要类型判断。不要假设它一定是 string:
if (typeof resp.result === 'string') {
const text = resp.result; // 安全
} else if (resp.result instanceof ArrayBuffer) {
const bytes = resp.result.byteLength; // ArrayBuffer 特有属性
}
七、实际应用场景
7.1 REST API 调用封装
class ApiClient {
private baseUrl: string = 'https://api.example.com';
get<T>(path: string): Promise<T> {
return this.request<T>(http.RequestMethod.GET, path);
}
post<T>(path: string, data: Object): Promise<T> {
return this.request<T>(http.RequestMethod.POST, path, data);
}
private request<T>(method: http.RequestMethod, path: string, data?: Object): Promise<T> {
return new Promise<T>((resolve, reject) => {
const httpReq = http.createHttp();
const options: http.HttpRequestOptions = {
method: method,
header: { 'Content-Type': 'application/json' },
expectDataType: http.HttpDataType.STRING,
connectTimeout: 10000,
readTimeout: 10000
};
if (data) {
options.extraData = JSON.stringify(data);
}
httpReq.request(this.baseUrl + path, options).then((resp) => {
httpReq.destroy();
if (resp.responseCode >= 200 && resp.responseCode < 300) {
resolve(JSON.parse(resp.result as string) as T);
} else {
reject(new Error('HTTP ' + resp.responseCode));
}
}).catch((e) => {
httpReq.destroy();
reject(e);
});
});
}
}
7.2 文件下载
private downloadFile(url: string): Promise<ArrayBuffer> {
const httpReq = http.createHttp();
return httpReq.request(url, {
method: http.RequestMethod.GET,
expectDataType: http.HttpDataType.ARRAY_BUFFER,
readTimeout: 60000
}).then((resp) => {
httpReq.destroy();
return resp.result as ArrayBuffer;
}).catch((e) => {
httpReq.destroy();
throw e;
});
}
7.3 监听响应头
const httpReq = http.createHttp();
httpReq.on('headersReceive', (header: Object) => {
console.log('响应头已接收:', JSON.stringify(header));
});
httpReq.request(url, options).then((resp) => {
// 处理响应体
httpReq.destroy();
});
headersReceive 事件在响应头到达时立即触发,早于响应体数据完全接收。这允许你在完整数据到达前就获取 Content-Type、Content-Length 等信息,对于大文件下载时的进度提示非常有用。
八、总结
@ohos.net.http 是 HarmonyOS NEXT 中进行 HTTP 网络请求的标准模块。通过本文的学习,你应该已经掌握:
- 三步模式:
createHttp()创建实例 →request(url, options)发请求 →destroy()销毁实例,资源管理清晰明确 - 请求配置:
HttpRequestOptions包含 method、header、extraData、expectDataType、connectTimeout、readTimeout 等完整配置项 - 请求方法:
RequestMethod枚举支持 GET/POST/PUT/DELETE 等 9 种 HTTP 方法,覆盖 RESTful API 全部需求 - 数据类型:
HttpDataType三选一(STRING/ARRAY_BUFFER/OBJECT),控制响应体 result 的类型 - 权限配置:需
ohos.permission.INTERNET权限(normal 级别,声明即授权) - ArkTS 限制:extraData 只能传 string 或 ArrayBuffer,普通对象需
JSON.stringify()转换
@ohos.net.http 的最佳使用模式可以总结为:
每个请求一个实例,Promise 异步处理,finally 中销毁,合理配置超时。
网络请求是应用与服务端交互的基础设施。优秀的 HTTP 客户端封装应当透明地处理超时重试、错误降级、日志追踪和资源释放。@ohos.net.http 提供了底层的 HTTP 能力,在此之上你可以构建适合自己业务的网络层抽象——无论是简单的 API 调用还是复杂的文件上传下载。
@ohos.net.http 属于 @kit.NetworkKit,与 Android 的 HttpURLConnection / OkHttp 和 iOS 的 URLSession 定位一致。它的 API 体积小巧但功能完整:9 种 HTTP 方法、3 种响应类型、完整的超时控制、代理支持、HTTPS 双向认证——对于绝大多数移动应用场景来说已经足够。
更多推荐


所有评论(0)