1. HTTP协议基础与鸿蒙网络架构
HTTP协议是现代应用网络通信的基石,基于客户端-服务器模型工作。在鸿蒙生态中,网络通信能力主要由NetworkKit提供,它封装了强大的HTTP客户端功能,支持所有常见的HTTP方法,包括GET、POST、PUT、DELETE等。
核心特点:
-
请求从客户端发出,服务器端响应:通信总是由客户端发起,服务器端在没有接收到请求之前不会发送响应
-
完整的HTTP方法支持:满足RESTful API设计需求
-
异步处理机制:基于Promise和async/await,保证UI流畅性
2. 开发前准备:权限与配置
2.1 网络权限申请
在应用的module.json5文件中添加网络访问权限:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
}
}
这是使用HTTP功能的前提条件,没有此权限应用将无法进行任何网络访问。
2.2 HTTP明文传输配置(如需要)
如果访问的服务器使用HTTP而非HTTPS,需要在config.json中启用明文传输:
{
"deviceConfig": {
"default": {
"network": {
"cleartextTraffic": true
}
}
}
}
3. 核心实现方案:基于http模块
3.1 基础使用步骤
鸿蒙系统的@kit.NetworkKit中的http模块是进行HTTP请求的主要方式。
1. 导入模块
import { http } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
2. 创建请求对象
// 每一个httpRequest对应一个HTTP请求任务,不可复用
let httpRequest = http.createHttp();
3. 订阅响应头事件(可选)
httpRequest.on('headersReceive', (header: Object) => {
console.info('header: ' + JSON.stringify(header));
});
此接口会比request请求先返回,可以根据业务需要订阅此消息。
4. 发起请求并处理响应
// 填写HTTP请求的URL地址,可以带参数也可以不带参数
httpRequest.request(
"https://api.example.com/data",
{
method: http.RequestMethod.GET, // 可选,默认为http.RequestMethod.GET
header: {
'Content-Type': 'application/json'
},
readTimeout: 60000, // 可选,默认为60000ms
connectTimeout: 60000, // 可选,默认为60000ms
},
(err: BusinessError, data: http.HttpResponse) => {
if (!err) {
// data.result为HTTP响应内容,可根据业务需要进行解析
console.info('Result:' + JSON.stringify(data.result));
console.info('code:' + JSON.stringify(data.responseCode));
// 取消订阅HTTP响应头事件
httpRequest.off('headersReceive');
// 请求完成后销毁对象
httpRequest.destroy();
} else {
console.error('error:' + JSON.stringify(err));
httpRequest.off('headersReceive');
httpRequest.destroy();
}
}
);
3.2 使用Promise风格
除了回调函数,http模块也支持Promise风格,使代码更简洁:
httpRequest.request('https://hmajax.itheima.net/api/news')
.then((data: http.HttpResponse) => {
if (data.responseCode === http.ResponseCode.OK) {
console.info('Result:' + data.result.toString());
// 处理请求结果
}
})
.catch((err: Error) => {
console.error('error:' + err.message);
})
.finally(() => {
httpRequest.destroy();
});
4. 进阶功能与配置
4.1 高级请求参数
http模块提供了丰富的高级配置选项:
httpRequest.request(
"https://api.example.com/upload",
{
method: http.RequestMethod.POST,
extraData: JSON.stringify({
"param1": "value1",
"param2": "value2"
}),
header: {
'Content-Type': 'application/json',
'Authorization': 'Bearer your-token-here'
},
usingCache: true, // 是否使用缓存
priority: 1, // 请求优先级
usingProtocol: http.HttpProtocol.HTTP1_1, // 使用协议
addressFamily: http.AddressFamily.DEFAULT // 地址族
}
);
4.2 文件上传
从API 11开始,支持multipart/form-data格式的文件上传:
multiFormDataList: [
{
name: "textPart",
contentType: 'text/plain',
data: 'Example data',
}, {
name: "filePart",
contentType: 'image/jpeg',
filePath: `${context.filesDir}/image.jpg`,
remoteFileName: 'image.jpg'
}
]
4.3 安全配置
鸿蒙提供了多种安全增强选项:
{
// 客户端证书配置(API 11+)
clientCert: {
certPath: '/path/to/client.pem',
keyPath: '/path/to/client.key',
keyPassword: "password"
},
// 证书锁定(API 12+)
certificatePinning: [
{
publicKeyHash: 'Pin1',
hashAlgorithm: 'SHA-256'
}
]
}
5. 异步处理最佳实践
5.1 Promise与async/await
使用async/await可以更优雅地处理异步请求:
async function fetchData(): Promise<void> {
try {
const httpRequest = http.createHttp();
const response = await httpRequest.request('https://api.example.com/data');
if (response.responseCode === http.ResponseCode.OK) {
const data = JSON.parse(response.result.toString());
// 处理数据
this.updateUI(data);
}
} catch (err) {
console.error('请求失败:', err.message);
} finally {
httpRequest.destroy();
}
}
// 使用示例
async function loadMultipleData(): Promise<void> {
const userData = await fetchUserData();
const productData = await fetchProductData();
// 并行请求
const [news, weather] = await Promise.all([
fetchNews(),
fetchWeather()
]);
}
5.2 JSON数据处理
网络请求通常涉及JSON数据的序列化和反序列化:
// 定义数据类型
interface User {
name: string;
age: number;
}
// JSON字符串转对象
const userStr = '{"name":"Jack","age":18}';
const user = JSON.parse(userStr) as User;
// 对象转JSON字符串
const newUserStr = JSON.stringify(user);
// 在HTTP请求中的应用
const requestData = {
userId: 123,
action: 'update'
};
httpRequest.request(
url,
{
method: http.RequestMethod.POST,
extraData: JSON.stringify(requestData),
header: {
'Content-Type': 'application/json'
}
}
);
6. 网络状态管理与优化
6.1 网络状态检测
在进行网络请求前,可以先检查网络状态:
import { connection } from '@kit.NetworkKit';
// 检查默认网络状态
const netManager = connection.getDefaultNet();
netManager.hasDefaultNet((err, data) => {
if (!err && data) {
// 有网络连接,发起请求
this.fetchData();
} else {
// 无网络连接,显示提示
this.showOfflineMessage();
}
});
6.2 订阅网络状态变化
// 订阅网络状态变化事件
netManager.on('netAvailable', (data) => {
console.info('网络已连接');
// 重新尝试失败的请求
this.retryFailedRequests();
});
netManager.on('netUnavailable', () => {
console.info('网络已断开');
// 显示离线状态
this.showOfflineMode();
});
7. 性能优化策略
7.1 请求优化技巧
-
减少不必要的数据传输
-
只请求需要的字段
-
使用增量更新而非全量数据
-
-
合理利用缓存
{ usingCache: true, // 启用缓存 // 其他参数... } -
连接复用
-
避免频繁创建和销毁连接
-
合理设置超时时间
-
7.2 智能网络切换
利用鸿蒙的网络管理功能,根据网络状况自动优化:
// 根据网络类型调整请求策略
private adjustRequestStrategy(netType: connection.NetBearType): void {
switch (netType) {
case connection.NetBearType.BEARER_WIFI:
// WiFi环境下可以预加载更多数据
this.preloadMoreData();
break;
case connection.NetBearType.BEARER_CELLULAR:
// 蜂窝网络下减少数据量
this.reduceDataUsage();
break;
}
}
8. 错误处理与调试
8.1 常见错误处理
private handleHttpError(error: BusinessError): void {
switch (error.code) {
case 401:
console.error('权限不足,请重新登录');
this.jumpToLogin();
break;
case 403:
console.error('访问被拒绝');
break;
case 404:
console.error('请求的资源不存在');
break;
case 408:
console.error('请求超时,请检查网络连接');
this.retryRequest();
break;
case 500:
console.error('服务器内部错误');
break;
default:
console.error('网络请求失败:', error.message);
}
}
8.2 请求重试机制
async function requestWithRetry(
url: string,
options: object,
maxRetries: number = 3
): Promise<void> {
let lastError: Error;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const httpRequest = http.createHttp();
const response = await httpRequest.request(url, options);
if (response.responseCode === http.ResponseCode.OK) {
return Promise.resolve(response);
}
} catch (err) {
lastError = err;
// 指数退避
await new Promise(resolve => {
setTimeout(resolve, Math.pow(2, attempt) * 1000);
});
}
}
return Promise.reject(lastError);
}
9. 实际应用场景示例
9.1 新闻列表获取
class NewsService {
async fetchNewsList(category: string, page: number = 1): Promise<News[]> {
const httpRequest = http.createHttp();
try {
const response = await httpRequest.request(
`https://api.news.com/news/${category}`,
{
method: http.RequestMethod.GET,
extraData: {
page: page,
pageSize: 20
}
}
);
if (response.responseCode === http.ResponseCode.OK) {
return JSON.parse(response.result.toString()).data as News[];
} else {
throw new Error(`HTTP错误: ${response.responseCode}`);
}
} finally {
httpRequest.destroy();
}
}
}
9.2 用户登录实现
async function userLogin(username: string, password: string): Promise<LoginResult> {
const httpRequest = http.createHttp();
try {
const response = await httpRequest.request(
'https://api.example.com/auth/login',
{
method: http.RequestMethod.POST,
extraData: JSON.stringify({
username: username,
password: password
}),
header: {
'Content-Type': 'application/json'
}
}
);
const result = JSON.parse(response.result.toString());
if (response.responseCode === http.ResponseCode.OK && result.success) {
// 保存登录状态
await this.saveAuthToken(result.token);
return { success: true, user: result.user };
} else {
return {
success: false,
error: result.message || '登录失败'
};
}
} catch (err) {
return {
success: false,
error: err.message
};
} finally {
httpRequest.destroy();
}
}
10. 总结
鸿蒙系统的HTTP网络请求框架提供了完整而强大的解决方案,从基础的请求发起到高级的安全配置,覆盖了各种应用场景的需求。关键要点包括:
-
权限配置是基础:确保正确配置网络权限和明文传输设置
-
资源管理很重要:及时销毁请求对象,避免内存泄漏
-
错误处理要全面:考虑各种网络异常情况
-
性能优化不可少:合理使用缓存、连接复用等策略
-
异步编程是核心:熟练使用Promise和async/await
通过掌握这些知识,你能够构建出稳定、高效且用户体验良好的鸿蒙应用。在实际开发中,建议根据具体业务需求选择合适的配置和优化策略,并充分利用鸿蒙系统提供的网络状态管理能力,打造真正智能的分布式应用体验。