HarmonyOS(鸿蒙) 中,HTTP 请求通过 RPC 实现时,不仅支持基础的请求和响应操作,还支持更复杂的应用场景,如并发请求、身份验证、请求头配置、流式处理等。在更复杂的网络环境下,开发者可能需要处理高级功能,如并行请求、请求超时、连接池、缓存机制以及自定义网络策略等。

本文将深入探讨 进阶的 HTTP 请求 相关技术,帮助你在实际开发中更加高效地使用 RPC 和 HTTP

✅ 一、进阶 HTTP 请求概述

  1. 并发请求和批量请求
    • 支持同时发起多个 HTTP 请求,提升性能,适用于批量操作。
  2. 身份验证与授权
    • 支持各种身份验证方式,如 OAuth2.0、JWT Token,保护敏感数据。
  3. 自定义请求头与超时设置
    • 自定义 HTTP 请求的头部信息,设置请求的超时时间,优化请求体验。
  4. 请求缓存
    • 基于网络条件和请求参数的缓存策略,减少不必要的请求,提高性能。
  5. 请求重试机制
    • 网络不稳定时,自动重试失败的请求,增强系统的健壮性。
  6. 流式数据处理
    • 处理大文件上传、下载和流式传输,支持逐步读取和传输数据。

✅ 二、并发请求与批量请求

在高并发场景下,发起多个并行的 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 AuthenticationOAuth2.0JWT(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.0JWT 都通过 Authorization 请求头传递认证信息,OAuth2.0 使用 Bearer token。

✅ 四、自定义请求头与超时设置

自定义 HTTP 请求头部可以满足不同的需求,比如设置 Content-TypeUser-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` 等。 |
| **超时设置**       | 设置请求超时时间,防止网络长时间无响应。               |
| **请求重试**       | 自动重试失败请求,增加系统的健壮性。                   |
| **流式处理**       | 支持大文件的流式上传和下载。                           |

这些技术可以在你的应用中大大提高灵活性和可用性,尤其适用于网络不稳定或有高并发需求的场景。