在 HarmonyOS(鸿蒙) 中,HTTP
请求通过 RPC
实现时,不仅支持基础的请求和响应操作,还支持更复杂的应用场景,如并发请求、身份验证、请求头配置、流式处理等。在更复杂的网络环境下,开发者可能需要处理高级功能,如并行请求、请求超时、连接池、缓存机制以及自定义网络策略等。
本文将深入探讨 进阶的 HTTP 请求 相关技术,帮助你在实际开发中更加高效地使用 RPC 和 HTTP。
✅ 一、进阶 HTTP 请求概述
- 并发请求和批量请求:
- 支持同时发起多个 HTTP 请求,提升性能,适用于批量操作。
- 身份验证与授权:
- 支持各种身份验证方式,如 OAuth2.0、JWT Token,保护敏感数据。
- 自定义请求头与超时设置:
- 自定义 HTTP 请求的头部信息,设置请求的超时时间,优化请求体验。
- 请求缓存:
- 基于网络条件和请求参数的缓存策略,减少不必要的请求,提高性能。
- 请求重试机制:
- 网络不稳定时,自动重试失败的请求,增强系统的健壮性。
- 流式数据处理:
- 处理大文件上传、下载和流式传输,支持逐步读取和传输数据。
✅ 二、并发请求与批量请求
在高并发场景下,发起多个并行的 HTTP 请求可以显著提升整体性能。鸿蒙通过 Promise.all()
方法来支持并行执行多个 HTTP 请求。
2.1 批量请求示例
import http from '@ohos.net.http';
async function fetchMultipleData() {
const urls = [
'https://example.com/api/data1',
'https://example.com/api/data2',
'https://example.com/api/data3'
];
try {
// 批量发送请求
let responses = await Promise.all(urls.map(url => http.get(url)));
// 处理每个请求的响应
for (let response of responses) {
let data = await response.readAsString();
console.log('数据:', data);
}
} catch (error) {
console.error('批量请求失败:', error);
}
}
Promise.all()
会并行发送多个请求,等待所有请求完成后再处理响应。- 当有任何一个请求失败时,
Promise.all()
会立刻抛出异常,适用于对请求结果有强依赖的场景。
2.2 限制并发请求数
有时你可能希望限制同时进行的请求数量,防止过多的并发请求导致服务器负载过重或应用崩溃。可以使用自定义的并发请求管理器来控制并发数。
import http from '@ohos.net.http';
// 简单的并发请求管理
async function fetchWithLimit(urls, limit) {
const results = [];
const queue = [];
// 控制并发数
for (let i = 0; i < urls.length; i++) {
if (queue.length >= limit) {
await Promise.race(queue); // 等待某个请求完成后,继续进行请求
}
const request = http.get(urls[i]).then(response => {
return response.readAsString();
});
queue.push(request);
request.finally(() => {
queue.splice(queue.indexOf(request), 1);
});
results.push(request);
}
return Promise.all(results);
}
- 通过控制
queue
的长度,我们可以限制并发请求数,从而避免网络压力过大。
✅ 三、身份验证与授权
在很多情况下,HTTP 请求需要进行身份验证才能访问受保护的资源。常见的身份验证方式包括 Basic Authentication、OAuth2.0 和 JWT(JSON Web Token)。
3.1 基本身份验证(Basic Auth)
基本身份验证通过在 HTTP 请求头部添加用户名和密码来进行身份验证。
async function fetchDataWithBasicAuth() {
const url = 'https://example.com/protected-data';
const credentials = 'username:password'; // 用户名和密码
const base64Credentials = btoa(credentials); // 转换为 Base64 编码
try {
const response = await http.get(url, {
'Authorization': `Basic ${base64Credentials}` // 添加认证信息到请求头
});
const data = await response.readAsString();
console.log('获取的敏感数据:', data);
} catch (error) {
console.error('身份验证失败:', error);
}
}
3.2 OAuth2.0 或 JWT 认证
对于更加安全的应用,OAuth2.0 或 JWT 认证是常见的解决方案。JWT 可以携带更多的身份信息,支持无状态的认证机制。
async function fetchDataWithJWT() {
const url = 'https://example.com/protected-data';
const token = 'your_jwt_token_here';
try {
const response = await http.get(url, {
'Authorization': `Bearer ${token}` // 添加 Bearer Token 到请求头
});
const data = await response.readAsString();
console.log('获取的敏感数据:', data);
} catch (error) {
console.error('JWT 认证失败:', error);
}
}
- OAuth2.0 和 JWT 都通过
Authorization
请求头传递认证信息,OAuth2.0 使用Bearer
token。
✅ 四、自定义请求头与超时设置
自定义 HTTP 请求头部可以满足不同的需求,比如设置 Content-Type
、User-Agent
或处理跨域请求等。
4.1 自定义请求头
async function sendDataWithHeaders() {
const url = 'https://example.com/api/data';
const data = JSON.stringify({ key: 'value' });
const headers = {
'Content-Type': 'application/json',
'User-Agent': 'MyApp/1.0.0',
'Custom-Header': 'customValue' // 自定义请求头
};
try {
const response = await http.post(url, data, headers);
const result = await response.readAsString();
console.log('数据提交成功:', result);
} catch (error) {
console.error('请求失败:', error);
}
}
- 通过传递一个包含
header
信息的对象,可以自定义请求头。
4.2 请求超时设置
为 HTTP 请求设置超时时间,避免网络长时间无响应导致的应用卡顿。
async function fetchDataWithTimeout() {
const url = 'https://example.com/api/data';
const timeout = 5000; // 设置请求超时时间为 5 秒
try {
const response = await http.get(url, { timeout: timeout });
const data = await response.readAsString();
console.log('数据获取成功:', data);
} catch (error) {
console.error('请求超时或失败:', error);
}
}
- 通过设置
timeout
参数,可以限制请求的最大等待时间。
✅ 五、请求缓存与重试机制
5.1 请求缓存
通过缓存机制,减少重复请求,提高性能。可以根据服务器响应头中的缓存策略(如 Cache-Control
)来决定是否缓存响应数据。
async function fetchDataWithCache() {
const url = 'https://example.com/api/data';
try {
let response = await http.get(url, { cache: 'only-if-cached' }); // 使用缓存(如果存在)
const data = await response.readAsString();
console.log('获取缓存数据:', data);
} catch (error) {
console.error('无法从缓存中获取数据:', error);
}
}
5.2 请求重试机制
当网络不稳定时,自动重试失败的请求可以增加系统的健壮性。
async function fetchDataWithRetry() {
const url = 'https://example.com/api/data';
const maxRetries = 3;
let retries = 0;
while (retries < maxRetries) {
try {
const response = await http.get(url);
const data = await response.readAsString();
console.log('数据获取成功:', data);
return;
} catch (error) {
retries++;
console.error(`请求失败,正在重试 ${retries}/${maxRetries}:`, error);
if (retries === maxRetries) {
console.error('重试次数已达到最大值');
}
}
}
}
- 在失败时,自动进行重试,直到达到最大重试次数。
✅ 六、流式数据传输
对于大文件的上传和下载,使用流式数据处理可以显著提高效率和降低内存占用。通过 getReader()
逐块读取数据,并进行处理。
async function downloadLargeFile() {
const url = 'https://example.com/largefile.zip';
const savePath =
‘/path/to/save/largefile.zip’;
try {
let response = await http.download(url, savePath);
const reader = response.getReader();
// 逐块读取并处理文件数据
let chunk;
while ((chunk = await reader.read()) !== null) {
console.log('正在下载文件:', chunk);
// 处理 chunk(如保存到磁盘等)
}
} catch (error) {
console.error('下载文件失败:', error);
}
}
- 通过 `getReader()`,开发者可以逐步读取下载文件的每个数据块,减少内存占用。
---
### ✅ 七、总结
通过 **RPC 和 HTTP**,HarmonyOS 提供了强大的网络请求能力,支持并发请求、身份验证、请求头设置、缓存、超时控制、重试机制等高级特性。在实际开发中,合理使用这些进阶特性能够显著提升应用性能和用户体验。
| 特性 | 描述 |
|--------------------|--------------------------------------------------------|
| **并发请求** | 使用 `Promise.all()` 和请求管理器来进行批量请求。 |
| **身份验证** | 支持 Basic Auth 和 JWT 认证等方式。 |
| **自定义请求头** | 允许自定义请求头,如 `Content-Type`、`User-Agent` 等。 |
| **超时设置** | 设置请求超时时间,防止网络长时间无响应。 |
| **请求重试** | 自动重试失败请求,增加系统的健壮性。 |
| **流式处理** | 支持大文件的流式上传和下载。 |
这些技术可以在你的应用中大大提高灵活性和可用性,尤其适用于网络不稳定或有高并发需求的场景。
发表回复