HTTP 网络请求
在 HarmonyOS 5.0 中,我们可以使用@ohos.net.http 模块封装基于 Promise 的 HTTP 请求。以下是完整实现方案:
流程图

效果图

添加网络权限
- 在
module.json5
中添加网络权限:
json
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
}
}
(1) 创建 Promise 封装工具 (httpUtil.ts)
ts
import http from "@ohos.net.http";
import { BusinessError } from "@ohos.base";
interface ResType {
code: number;
msg: string;
data: object;
}
// 定义请求配置类型
type RequestConfig = {
url: string;
method?:
| http.RequestMethod.GET
| http.RequestMethod.POST
| http.RequestMethod.PUT
| http.RequestMethod.DELETE;
header?: Object;
body?: string | Object;
};
// 封装HTTP请求
export function httpRequest(config: RequestConfig): Promise<any> {
return new Promise((resolve, reject) => {
// 1. 创建HTTP客户端
const httpRequest = http.createHttp();
// 2. 处理请求体(对象转JSON字符串)
let requestBody = config.body;
if (typeof config.body === "object") {
requestBody = JSON.stringify(config.body);
config.header = {
...config.header,
"Content-Type": "application/json",
};
}
// 3. 发送请求
httpRequest.request(
config.url,
{
method: config.method || http.RequestMethod.GET,
header: config.header || {},
extraData: requestBody,
},
(err: BusinessError, response: http.HttpResponse) => {
// 4. 处理响应
if (err) {
httpRequest.destroy(); // 释放资源
reject(new Error(`Network error: ${err.code} - ${err.message}`));
return;
}
// 5. 检查状态码
if (response.responseCode >= 200 && response.responseCode < 300) {
try {
// 6. 尝试解析JSON
// 表示成功了 这里只能用String 不能用JSON.stringify
let res: ResType = response.result as ResType;
let result = JSON.parse(String(res));
if (result.code == 200) {
resolve(result.data);
} else {
resolve(result.msg);
}
} catch (e) {
resolve(response.result); // 返回原始数据
}
} else {
reject(new Error(`HTTP ${response.responseCode}: ${response}`));
}
// 7. 释放资源
httpRequest.destroy();
}
);
});
}
// 快捷方法
export const httpGet = async <T>(
url: string,
header?: Object
): Promise<ResType> => {
return await httpRequest({ url, method: http.RequestMethod.GET, header });
};
export const httpPost = async <T>(
url: string,
body: Object | string,
header?: Object
): Promise<ResType> => {
return await httpRequest({
url,
method: http.RequestMethod.POST,
body,
header,
});
};
(2)业务中使用
ts
import { httpGet, httpPost } from "../utils/httpUtils";
interface ResType {
code: number;
msg: string;
data: object;
}
class IndexApi {
public baseurl: string = "https://newapidev.dianyuan.com";
// 获取数据
async getUserData() {
try {
const url = "/page/v2025/tek250612/getInfo";
const result: object = await httpPost(
this.baseurl + url,
{},
{
"Access-Token": "xxxxxxxx",
"Client-Type": "web",
Sign: "xxxxxxx",
}
);
console.log("888999");
console.log(JSON.stringify(result));
return result;
} catch (error) {
console.log("请求失败" + error.message);
return `请求失败 + ${error.message}`;
}
}
}
const IndexClassApi = new IndexApi();
export default IndexClassApi;
ts
import IndexClassApi from "../api/IndexApi"
import { JSON } from "@kit.ArkTS";
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
build() {
Column() {
Button("点击").type(ButtonType.Normal).onClick(async () => {
const result = await IndexClassApi.getUserData()
console.log("9999")
console.log(JSON.stringify(result))
})
}
}
}
补充
添加超时控制
ts
// 在request配置中添加
httpRequest.request(config.url, {
connectTimeout: 30000, // 30秒超时
// ...其他配置
});
添加重试机制
ts
async function requestWithRetry(config: RequestConfig, retries = 3) {
try {
return await httpRequest(config);
} catch (error) {
if (retries > 0) {
await new Promise((resolve) => setTimeout(resolve, 1000));
return requestWithRetry(config, retries - 1);
}
throw error;
}
}
添加请求拦截器
ts
// 全局请求拦截示例
const originalRequest = httpRequest;
httpRequest = async (config) => {
// 添加全局token
config.header = {
...config.header,
Authorization: `Bearer ${getGlobalToken()}`,
};
return originalRequest(config);
};