|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "鸿蒙 Next 实战:集成阿里云 HTTPDNS 优化网络请求" |
| 4 | +date: 2025-12-31 10:00:00 +0800 |
| 5 | +categories: harmonyos network |
| 6 | +tags: harmonyos httpdns network optimization |
| 7 | +--- |
| 8 | + |
| 9 | +在移动应用开发中,域名劫持和解析延迟是常见的网络问题。为了提升网络连接的稳定性和速度,引入 HTTPDNS 是一个非常有效的方案。本文将分享如何在鸿蒙 HarmonyOS Next 项目中集成阿里云 HTTPDNS(`@aliyun/httpdns`)并结合 Axios 实现自定义 DNS 解析。 |
| 10 | + |
| 11 | +## 1. 引入依赖 |
| 12 | + |
| 13 | +首先,我们需要在项目的 `oh-package.json5` 中引入阿里云 HTTPDNS 的 SDK 和 Axios。 |
| 14 | + |
| 15 | +```json |
| 16 | +"dependencies": { |
| 17 | + "@aliyun/httpdns": "^1.0.1", |
| 18 | + "@ohos/axios": "^2.2.0" |
| 19 | +} |
| 20 | +``` |
| 21 | + |
| 22 | +执行 `ohpm install` 安装依赖。 |
| 23 | + |
| 24 | +## 2. 封装 HttpDnsManager |
| 25 | + |
| 26 | +为了方便管理和调用,我们封装一个单例类 `HttpDnsManager`。这个类主要负责 SDK 的初始化和提供 DNS 解析方法。 |
| 27 | + |
| 28 | +创建 `HttpDnsManager.ets`: |
| 29 | + |
| 30 | +```typescript |
| 31 | +import { httpdns, IHttpDnsService, HttpDnsResult } from '@aliyun/httpdns'; |
| 32 | +import { connection } from '@kit.NetworkKit'; |
| 33 | +import common from '@ohos.app.ability.common'; |
| 34 | + |
| 35 | +export class HttpDnsManager { |
| 36 | + private static instance: HttpDnsManager; |
| 37 | + private httpDnsService: IHttpDnsService | undefined; |
| 38 | + |
| 39 | + // 替换为你自己的阿里云 Account ID |
| 40 | + private static readonly ALIYUN_ACCOUNT_ID = "105310"; |
| 41 | + |
| 42 | + private constructor() { |
| 43 | + } |
| 44 | + |
| 45 | + public static getInstance(): HttpDnsManager { |
| 46 | + if (!HttpDnsManager.instance) { |
| 47 | + HttpDnsManager.instance = new HttpDnsManager(); |
| 48 | + } |
| 49 | + return HttpDnsManager.instance; |
| 50 | + } |
| 51 | + |
| 52 | + /** |
| 53 | + * 初始化 HTTPDNS 服务 |
| 54 | + * @param context UIAbilityContext |
| 55 | + * @param accountId 阿里云 Account ID |
| 56 | + */ |
| 57 | + public init(context: common.UIAbilityContext, accountId: string = HttpDnsManager.ALIYUN_ACCOUNT_ID) { |
| 58 | + // 1. 配置服务上下文 |
| 59 | + httpdns.configService(accountId, { |
| 60 | + context: context |
| 61 | + }); |
| 62 | + |
| 63 | + // 2. 异步获取服务实例 |
| 64 | + httpdns.getService(accountId).then((service) => { |
| 65 | + this.httpDnsService = service; |
| 66 | + }).catch((err: Error) => { |
| 67 | + console.error("HttpDns init failed: " + JSON.stringify(err)); |
| 68 | + }); |
| 69 | + } |
| 70 | + |
| 71 | + /** |
| 72 | + * 自定义 DNS 解析方法 (供 Axios 调用) |
| 73 | + */ |
| 74 | + public async lookup(hostname: string): Promise<Array<connection.NetAddress>> { |
| 75 | + if (!this.httpDnsService) { |
| 76 | + // 服务未初始化,返回空让 Axios 走默认系统 DNS |
| 77 | + return []; |
| 78 | + } |
| 79 | + |
| 80 | + try { |
| 81 | + // 异步获取解析结果,内部包含了缓存策略:有缓存用缓存,无缓存请求网络 |
| 82 | + let result: HttpDnsResult = await this.httpDnsService.getHttpDnsResultAsync(hostname); |
| 83 | + |
| 84 | + let netAddresses: Array<connection.NetAddress> = []; |
| 85 | + |
| 86 | + // 处理 IPv4 结果 |
| 87 | + if (result.ipv4s && result.ipv4s.length > 0) { |
| 88 | + for (let ip of result.ipv4s) { |
| 89 | + netAddresses.push({ |
| 90 | + address: ip, |
| 91 | + family: 1, // 1 代表 IPv4 (AF_INET) |
| 92 | + port: 0 |
| 93 | + }); |
| 94 | + } |
| 95 | + } |
| 96 | + |
| 97 | + // 处理 IPv6 结果 |
| 98 | + if (result.ipv6s && result.ipv6s.length > 0) { |
| 99 | + for (let ip of result.ipv6s) { |
| 100 | + netAddresses.push({ |
| 101 | + address: ip, |
| 102 | + family: 2, // 2 代表 IPv6 (AF_INET6) |
| 103 | + port: 0 |
| 104 | + }); |
| 105 | + } |
| 106 | + } |
| 107 | + |
| 108 | + return netAddresses; |
| 109 | + } catch (e) { |
| 110 | + console.error("HttpDns lookup failed: " + JSON.stringify(e)); |
| 111 | + return []; |
| 112 | + } |
| 113 | + } |
| 114 | +} |
| 115 | +``` |
| 116 | + |
| 117 | +## 3. 在 Axios 中应用 |
| 118 | + |
| 119 | +Axios 自 `2.2.0` 版本起支持自定义 `dns.lookup` 配置。我们可以将 `HttpDnsManager` 的 `lookup` 方法注入到 Axios 中。 |
| 120 | + |
| 121 | +### 全局配置 |
| 122 | + |
| 123 | +如果你希望项目中所有的 Axios 请求都走 HTTPDNS: |
| 124 | + |
| 125 | +```typescript |
| 126 | +import axios from '@ohos/axios'; |
| 127 | +import { HttpDnsManager } from './HttpDnsManager'; // 假设路径 |
| 128 | + |
| 129 | +// 配置 Axios 默认的 DNS 解析 |
| 130 | +axios.defaults.dns = { |
| 131 | + lookup: async (hostname: string) => { |
| 132 | + // 获取 HTTPDNS 解析结果 |
| 133 | + return await HttpDnsManager.getInstance().lookup(hostname); |
| 134 | + } |
| 135 | +}; |
| 136 | +``` |
| 137 | + |
| 138 | +### 实例配置 |
| 139 | + |
| 140 | +如果你只想为特定的请求实例开启 HTTPDNS: |
| 141 | + |
| 142 | +```typescript |
| 143 | +import axios from '@ohos/axios'; |
| 144 | +import { HttpDnsManager } from './HttpDnsManager'; |
| 145 | + |
| 146 | +const request = axios.create({ |
| 147 | + baseURL: 'https://api.yourdomain.com', |
| 148 | + timeout: 10000, |
| 149 | + dns: { |
| 150 | + lookup: async (hostname: string) => { |
| 151 | + return await HttpDnsManager.getInstance().lookup(hostname); |
| 152 | + } |
| 153 | + } |
| 154 | +}); |
| 155 | +``` |
| 156 | + |
| 157 | +## 4. 全局初始化 |
| 158 | + |
| 159 | +最后,别忘了在应用的入口 `EntryAbility` 中初始化 `HttpDnsManager`: |
| 160 | + |
| 161 | +```typescript |
| 162 | +import { HttpDnsManager } from '@jzdy/common'; // 你的模块路径 |
| 163 | + |
| 164 | +export default class EntryAbility extends UIAbility { |
| 165 | + onCreate(want, launchParam) { |
| 166 | + // ... |
| 167 | + // 初始化 HTTPDNS |
| 168 | + HttpDnsManager.getInstance().init(this.context); |
| 169 | + // ... |
| 170 | + } |
| 171 | +} |
| 172 | +``` |
| 173 | + |
| 174 | +## 总结 |
| 175 | + |
| 176 | +通过以上方式,我们成功将阿里云 HTTPDNS 集成到了鸿蒙应用的 Axios 网络栈中。 |
| 177 | +1. **HttpDnsManager**:负责与阿里云 SDK 交互,提供统一的解析接口。 |
| 178 | +2. **Axios DNS Config**:利用 `config.dns.lookup` 钩子,拦截 DNS 解析过程,替换为 HTTPDNS 的结果。 |
| 179 | + |
| 180 | +这种方案侵入性小,且充分利用了 Axios 的扩展能力,是鸿蒙网络优化的最佳实践之一。 |
| 181 | + |
| 182 | +## 5. 参考资料 |
| 183 | + |
| 184 | +* [阿里云 HTTPDNS 产品文档](https://help.aliyun.com/product/37963.html) - 获取 Account ID 及控制台配置 |
| 185 | +* [OpenHarmony Axios 组件](https://ohpm.openharmony.cn/#/cn/detail/@ohos%2Faxios) - Axios for HarmonyOS |
| 186 | +* [阿里云 HTTPDNS HarmonyOS SDK (OHPM)](https://ohpm.openharmony.cn/#/cn/detail/@aliyun%2Fhttpdns) - SDK 下载及更新日志 |
| 187 | +* [自定义 DNS 解析配置参考](https://gitee.com/openharmony-sig/ohos_axios#%E8%87%AA%E5%AE%9A%E4%B9%89dns) - Axios 自定义 DNS 文档 |
0 commit comments