HarmonyOS之网络请求从入门到生产:@ohos.net.http 一篇吃透
·
鸿蒙网络请求从入门到生产:@ohos.net.http 一篇吃透
引言
App 不做网络请求?那基本是个单机游戏。HarmonyOS 提供了 @ohos.net.http 模块作为标准 HTTP 通信方案,属于 @kit.NetworkKit。
本文从 GET/POST 基础请求开始,到拦截器封装、超时重试、取消请求,一步到位。
一、基础用法
import http from '@ohos.net.http';
1.1 最简 GET 请求
const req = http.createHttp();
req.request('https://api.example.com/users', {
method: http.RequestMethod.GET,
header: {
'Content-Type': 'application/json'
}
}).then((res: http.HttpResponse) => {
console.log('状态码:', res.responseCode);
console.log('响应体:', res.result as string);
console.log('响应头:', res.header);
}).catch((e: Error) => {
console.error('请求失败:', e.message);
}).finally(() => {
req.destroy(); // 释放连接
});
1.2 POST 请求 + JSON 数据
const req = http.createHttp();
req.request('https://api.example.com/login', {
method: http.RequestMethod.POST,
header: {
'Content-Type': 'application/json'
},
extraData: JSON.stringify({
username: 'admin',
password: '123456'
})
}).then((res) => {
const data = JSON.parse(res.result as string);
console.log('登录成功:', data.token);
}).catch((e) => {
console.error('登录失败:', e.message);
}).finally(() => {
req.destroy();
});
二、请求配置详解
完整配置项:
req.request(url, {
method: http.RequestMethod.GET, // 请求方法
header: { // 请求头
'Content-Type': 'application/json',
'Authorization': 'Bearer token123'
},
extraData: '', // 请求体
expectDataType: http.HttpDataType.STRING, // 期望返回类型
usingHttp2: true, // 启用HTTP/2
usingProtocol: http.HttpProtocol.HTTP1_1, // 协议版本
connectTimeout: 10000, // 连接超时(ms)
readTimeout: 30000, // 读取超时(ms)
usingProxy: false // 是否代理
});
| 配置项 | 默认值 | 说明 |
|---|---|---|
connectTimeout |
60000ms | 连接超时 |
readTimeout |
60000ms | 读取超时 |
expectDataType |
STRING | 返回数据类型 |
usingHttp2 |
false | 是否HTTP/2 |
usingProtocol |
HTTP1_1 | HTTP协议版本 |
三、统一封装:拦截器模式
生产项目不要每次都 createHttp + 手动配参数,封装一个统一请求工具:
class HttpClient {
private baseURL: string;
private token: string = '';
constructor(baseURL: string) {
this.baseURL = baseURL;
}
setToken(token: string) {
this.token = token;
}
private buildHeader(): object {
const header: Record<string, string> = {
'Content-Type': 'application/json'
};
if (this.token) {
header['Authorization'] = `Bearer ${this.token}`;
}
return header;
}
private handleError(e: Error): never {
console.error('网络错误:', e.message);
throw e;
}
async get<T>(path: string): Promise<T> {
const req = http.createHttp();
try {
const res = await req.request(this.baseURL + path, {
method: http.RequestMethod.GET,
header: this.buildHeader(),
connectTimeout: 10000,
readTimeout: 30000
});
return JSON.parse(res.result as string) as T;
} catch (e) {
this.handleError(e as Error);
} finally {
req.destroy();
}
}
async post<T>(path: string, data: object): Promise<T> {
const req = http.createHttp();
try {
const res = await req.request(this.baseURL + path, {
method: http.RequestMethod.POST,
header: this.buildHeader(),
extraData: JSON.stringify(data),
connectTimeout: 10000,
readTimeout: 30000
});
return JSON.parse(res.result as string) as T;
} catch (e) {
this.handleError(e as Error);
} finally {
req.destroy();
}
}
}
// 使用
const api = new HttpClient('https://api.example.com');
api.setToken('xxx');
const users = await api.get<User[]>('/users');
四、超时重试与请求取消
4.1 带重试的请求
async function requestWithRetry(url: string, maxRetries = 3): Promise<string> {
let lastError: Error | null = null;
for (let i = 0; i < maxRetries; i++) {
const req = http.createHttp();
try {
const res = await req.request(url, {
method: http.RequestMethod.GET,
connectTimeout: 5000,
readTimeout: 10000
});
return res.result as string;
} catch (e) {
lastError = e as Error;
console.log(`第${i + 1}次失败,准备重试...`);
// 指数退避:1s, 2s, 4s
await new Promise(r => setTimeout(r, 1000 * Math.pow(2, i)));
} finally {
req.destroy();
}
}
throw lastError;
}
4.2 取消请求
const req = http.createHttp();
// 设置超时取消
req.request('https://api.example.com/large-data', {
readTimeout: 5000 // 5秒没响应自动取消
});
// 主动取消
setTimeout(() => {
req.cancel(); // 请求将被取消
}, 3000);
五、文件上传与下载
5.1 上传文件(multipart/form-data)
const req = http.createHttp();
req.request('https://api.example.com/upload', {
method: http.RequestMethod.POST,
header: { 'Content-Type': 'multipart/form-data' },
extraData: {
name: 'avatar',
filePath: `${ctx.filesDir}/avatar.jpg`
}
});
5.2 下载文件
const req = http.createHttp();
req.request('https://example.com/image.png', {
method: http.RequestMethod.GET,
expectDataType: http.HttpDataType.ARRAY_BUFFER
}).then((res) => {
const buf = res.result as ArrayBuffer;
// 写入本地文件
let file = fs.openSync(`${ctx.filesDir}/downloaded.png`,
fs.OpenMode.CREATE | fs.OpenMode.WRITE_ONLY);
fs.writeSync(file.fd, buf);
fs.closeSync(file);
}).finally(() => req.destroy());
六、HTTPS与证书校验
const req = http.createHttp();
req.request('https://secure-api.example.com/data', {
method: http.RequestMethod.GET,
// 配置CA证书(可选,默认校验系统CA)
caPath: '/path/to/custom-ca.pem'
});
如果需要跳过证书校验(仅测试环境):
// 在 entry/src/main/module.json5 中配置
{
"network": {
"cleartext": true // 允许HTTP(非HTTPS)
}
}
七、最佳实践清单
✅ 必须做的
- 每次请求后 destroy():不释放会有连接泄漏
- 设置合理超时:connectTimeout 10s + readTimeout 30s
- 统一封装:不要满屏幕 createHttp
- try/catch 全面覆盖:网络请求随时可能失败
⚠️ 避坑指南
- 不要在主线程同步请求:
@ohos.net.http本身就是异步的,直接用 - 请求体用字符串:
extraData传对象可能序列化异常,先JSON.stringify - destroy 后不能再使用:每次请求创建新实例
- Header 大小限制:总header不超过8KB
总结
HarmonyOS 的网络请求不复杂:createHttp → request → then/catch → destroy 四步走。再加上统一的拦截器封装、超时重试,就能构建一个生产级的网络层。它是鸿蒙应用连接世界的窗口——简单、高效、可靠。
更多推荐




所有评论(0)