项目概述
智慧云购App(鸿蒙版)是一款基于OpenHarmony系统的电子商务应用,需要与后端服务器进行大量的网络交互。HttpClient插件为我们提供了高效、稳定、功能丰富的网络请求能力,是App与服务器通信的核心组件。

环境配置

  1. 安装HttpClient
    在项目根目录下执行命令安装HttpClient:

ohpm install @ohos/httpclient
2. 配置网络权限
在entry/src/main/ets/module.json5中添加网络权限:

json
“requestPermissions”: [
{
“name”: “ohos.permission.INTERNET”
},
{
“name”: “ohos.permission.GET_NETWORK_INFO”
}
]
全局配置
在应用启动时配置HttpClient全局参数:

import { HttpClient, TimeUnit } from ‘@ohos/httpclient’;

// 初始化HttpClient
export class HttpClientManager {
private static client: HttpClient;

public static initClient(): void {
this.client = new HttpClient.Builder()
.setConnectTimeout(15, TimeUnit.SECONDS) // 连接超时15秒
.setReadTimeout(30, TimeUnit.SECONDS) // 读取超时30秒
.setWriteTimeout(30, TimeUnit.SECONDS) // 写入超时30秒
.addInterceptor(new LoggingInterceptor()) // 添加日志拦截器
.build();
}

public static getClient(): HttpClient {
return this.client;
}
}
常用请求示例

  1. GET请求 - 获取商品列表
    import { HttpClient, Request, Logger } from ‘@ohos/httpclient’;

async function fetchProductList(categoryId: string) {
const client = HttpClientManager.getClient();
const request = new Request.Builder()
.get(https://api.smartshop.com/products?category=${categoryId})
.addHeader(“Authorization”, Bearer ${getAccessToken()})
.build();

try {
const response = await client.newCall(request).execute();
if (response && response.result) {
return JSON.parse(response.result);
}
return null;
} catch (error) {
Logger.error(获取商品列表失败: ${JSON.stringify(error)});
throw new Error(‘网络请求失败’);
}
}
2. POST请求 - 用户登录
import { HttpClient, Request, RequestBody, Mime, Logger } from ‘@ohos/httpclient’;

async function userLogin(username: string, password: string) {
const client = HttpClientManager.getClient();
const requestBody = {
username,
password: encryptPassword(password), // 密码加密
deviceId: getDeviceId()
};

const request = new Request.Builder()
.url(“https://api.smartshop.com/auth/login”)
.post(RequestBody.create(
requestBody,
new Mime.Builder()
.contentType(‘application/json’)
.build()
.getMime()
))
.build();

try {
const response = await client.newCall(request).execute();
if (response && response.result) {
const result = JSON.parse(response.result);
saveToken(result.token); // 保存token
return result.userInfo;
}
throw new Error(‘登录失败’);
} catch (error) {
Logger.error(用户登录失败: ${JSON.stringify(error)});
throw new Error(‘网络请求失败’);
}
}
3. 文件上传 - 用户头像更新
import { HttpClient, Request, FileUpload, Logger } from ‘@ohos/httpclient’;

async function uploadAvatar(filePath: string) {
const client = HttpClientManager.getClient();
const context = getContext();

// 转换文件路径为internal格式
const internalPath = filePath.replace(context.cacheDir, “internal://cache”);

const fileUploadBuilder = new FileUpload.Builder()
.addFile(internalPath)
.addData(“type”, “avatar”)
.build();

const request = new Request.Builder()
.url(“https://api.smartshop.com/user/avatar”)
.method(“POST”)
.body(fileUploadBuilder)
.setAbilityContext(context)
.addHeader(“Authorization”, Bearer ${getAccessToken()})
.build();

try {
const response = await client.newCall(request).execute();
if (response && response.result) {
return JSON.parse(response.result);
}
throw new Error(‘上传失败’);
} catch (error) {
Logger.error(头像上传失败: ${JSON.stringify(error)});
throw new Error(‘网络请求失败’);
}
}
4. 文件下载 - 商品图片缓存
import { HttpClient, Request, Logger } from ‘@ohos/httpclient’;

async function downloadProductImage(url: string, savePath: string) {
const client = HttpClientManager.getClient();
const context = getContext();

try {
const request = new Request.Builder()
.download(url, savePath)
.setAbilityContext(context)
.build();

return new Promise((resolve, reject) => {
  client.newCall(request).enqueue(
    (data) => {
      data.downloadTask.on('complete', () => {
        Logger.info("图片下载完成");
        resolve(true);
      });
      
      data.downloadTask.on("progress", (receivedSize, totalSize) => {
        const progress = Math.round((receivedSize / totalSize) * 100);
        Logger.info(`下载进度: ${progress}%`);
      });
    },
    (error) => {
      Logger.error(`图片下载失败: ${JSON.stringify(error)}`);
      reject(error);
    }
  );
});

} catch (error) {
Logger.error(图片下载异常: ${JSON.stringify(error)});
throw new Error(‘网络请求失败’);
}
}
高级功能实现

  1. 请求取消 - 防止重复提交
    typescript
    import { HttpClient, Request, Logger } from ‘@ohos/httpclient’;

// 在页面或组件中
let currentRequestTag: string | null = null;

async function submitOrder(orderData: any) {
// 如果已有请求在进行中,先取消
if (currentRequestTag) {
HttpClientManager.getClient().cancelRequestByTag(currentRequestTag);
}

const tag = order_${Date.now()};
currentRequestTag = tag;

const client = HttpClientManager.getClient();
const request = new Request.Builder()
.url(“https://api.smartshop.com/orders”)
.post(RequestBody.create(orderData, ‘application/json’))
.tag(tag)
.build();

try {
const response = await client.newCall(request).execute();
if (response && response.result) {
currentRequestTag = null;
return JSON.parse(response.result);
}
throw new Error(‘提交失败’);
} catch (error) {
if (error.code !== 1001) { // 1001通常是取消请求的错误码
Logger.error(订单提交失败: ${JSON.stringify(error)});
}
throw error;
}
}
2. 自定义拦截器 - 日志和认证
class LoggingInterceptor implements HttpInterceptor {
intercept(chain: InterceptorChain): Promise {
const request = chain.request();
const startTime = Date.now();

Logger.info(`开始请求: ${request.url()} ${request.method()}`);

return chain.proceed(request).then((response) => {
  const endTime = Date.now();
  Logger.info(`请求完成: ${request.url()} 耗时: ${endTime - startTime}ms 状态码: ${response.responseCode}`);
  return response;
}).catch((error) => {
  const endTime = Date.now();
  Logger.error(`请求失败: ${request.url()} 耗时: ${endTime - startTime}ms 错误: ${JSON.stringify(error)}`);
  throw error;
});

}
}

class AuthInterceptor implements HttpInterceptor {
intercept(chain: InterceptorChain): Promise {
const request = chain.request();

// 添加认证头
const newRequest = request.newBuilder()
  .addHeader("Authorization", `Bearer ${getAccessToken()}`)
  .build();

return chain.proceed(newRequest);

}
}
3. 分片上传 - 大文件上传
async function uploadLargeFile(filePath: string, fileName: string) {
const client = HttpClientManager.getClient();
const context = getContext();

const fileUploadBuilder = new BinaryFileChunkUpload.Builder()
.addBinaryFile(context, {
filePath: filePath,
fileName: fileName,
chunkSize: 1024 * 1024 * 4, // 4MB分片
name: ‘file’
})
.addData(‘type’, ‘product_video’)
.addUploadProgress((progress) => {
// 更新UI显示上传进度
updateUploadProgress(progress);
})
.build();

const request = new Request.Builder()
.url(“https://api.smartshop.com/upload/chunk”)
.setAbilityContext(context)
.body(fileUploadBuilder)
.build();

try {
const response = await client.newCall(request).execute();
if (response && response.result) {
return JSON.parse(response.result);
}
throw new Error(‘上传失败’);
} catch (error) {
Logger.error(大文件上传失败: ${JSON.stringify(error)});
throw new Error(‘网络请求失败’);
}
}
最佳实践
全局单例管理:在整个应用中只维护一个HttpClient实例,通过单例模式管理。
错误处理:
统一处理网络错误和业务错误
对常见错误码进行特殊处理(如token过期自动刷新)
性能优化:
合理设置超时时间
使用连接池管理
对频繁请求的接口进行缓存
安全实践:
敏感数据加密传输
使用HTTPS协议
重要接口添加证书锁定
监控与日志:
记录关键请求的耗时
监控失败请求的比例
记录慢请求
常见问题解决
证书验证失败:
确保服务器证书有效
如需跳过验证(仅测试环境):

.sslSocketFactory(new TrustAllCerts(), new TrustAllHosts())
.hostnameVerifier((hostname, session) => true)
跨域问题:
确保服务器配置了正确的CORS头
在开发阶段可配置代理
大文件上传失败:
检查文件权限
确保分片大小合理
实现断点续传逻辑
内存泄漏:
及时取消不再需要的请求
避免在拦截器中持有强引用
通过合理使用HttpClient插件提供的丰富功能,智慧云购App能够为用户提供流畅、安全的网络体验,支撑起整个应用的业务逻辑。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐