【HarmonyOS】鸿蒙应用HTTPDNS 服务集成详解

【HarmonyOS】鸿蒙应用HTTPDNS 服务集成详解

一、前言

鸿蒙应用HTTPDNS 服务集成,首先需要理解基本概念。HTTPDNS是什么?干嘛用的呢?从这个问题又会延伸出DNS是什么。接下来我们逐个讲解。再之后进行HTTPDNS服务集成得步骤讲解。

二、DNS是什么?

DNS 是互联网的核心基础设施,核心功能是将人类可读的域名如www.baidu.com)转换为机器可识别的 IP 地址(如 180.101.50.242),让设备能够通过 IP 定位并访问网络资源。

说白了,DNS就是个将网站域名翻译成具体IP的设施。

工作原理: 基于 UDP 协议(端口 53),解析过程通常需要经过本地 DNS 缓存、根域名服务器、顶级域名服务器(如.com)、权威域名服务器等多级节点,最终返回 IP 地址。

问题: 依赖本地 DNS(如运营商提供的 DNS 服务器),可能存在域名劫持(解析结果被篡改,跳转到恶意网站)、调度不精准(本地 DNS 可能返回距离用户较远的 IP,导致访问卡顿)、缓存污染(旧 IP 缓存未更新,导致访问失败)等问题。

三、HTTPDNS是什么?

HTTPDNS 是一种基于 HTTP 协议的新型域名解析技术,核心是绕过传统 DNS 的解析路径,直接通过 HTTP/HTTPS 请求向专用解析服务器(如阿里云、腾讯云的 HTTPDNS 服务器)获取 IP 地址,从而解决传统 DNS 的痛点。

工作原理: 应用(如 App)通过 HTTP 协议向服务商的 HTTPDNS 服务器发送请求(携带需要解析的域名),服务器直接返回精准的 IP 地址(通常基于用户地理位置、网络状况等调度最优 IP),应用再用该 IP 直接发起网络请求。

优势: 避免域名劫持:不依赖本地 DNS,解析结果由服务商直接返回,更安全; 调度精准:服务商可根据用户实际网络情况返回最优 IP,减少访问延迟; 实时性强:绕过本地 DNS 缓存,可快速获取最新 IP(如服务器 IP 变更时)。

四、如何集成HTTPDNS服务?

综上所述,我们已经对HTTPDNS有了基本了解。所以集成该服务。无非是选择对应的服务商。华为云、腾讯云或者阿里云。

以下是整合华为云、腾讯云、阿里云三家HTTPDNS服务的鸿蒙应用集成方案,包含通用准备、各厂商具体实现、统一工具封装及注意事项,方便开发者按需选择或切换服务商。

1、通用准备工作(三家共需)

开通对应云厂商的HTTPDNS服务,获取核心认证信息(如账号ID、密钥等);

鸿蒙应用需声明网络权限:在module.json5中添加"ohos.permission.INTERNET"

确保设备系统版本为HarmonyOS Next(API 12+) ,支持connection模块的addCustomDnsRule等接口。

通过HTTP协议向云厂商的专用服务器解析域名,获取IP地址后,利用鸿蒙系统API强制域名与IP绑定,绕过传统DNS,解决劫持、调度不精准等问题。

2、各厂商集成方案详解

(1)华为云HTTPDNS集成

华为云通过"云解析服务"提供HTTPDNS能力,需调用其RESTful API。

1. 开通服务与获取信息

登录华为云控制台,开通"云解析服务"。

typescript 复制代码
https://console.huaweicloud.com/dns

获取AK(Access Key)SK(Secret Key)项目ID(在"我的凭证"中创建),添加需解析的域名并配置A记录(IP地址)。

2. 核心实现代码(含API认证)
typescript 复制代码
import { http } from '@ohos.net.http';
import { connection } from '@ohos.net.connection';
import { sign } from './huawei-sign'; // 需实现华为云API签名逻辑(见备注)

// 华为云DNS解析API地址(查询域名的A记录)
function getHuaweiApiUrl(projectId: string, domain: string): string {
  return `https://dns.myhuaweicloud.com/v2/${projectId}/recordsets?name=${domain}&type=A`;
}

// 解析域名并设置DNS规则
export async function resolveWithHuawei(domain: string): Promise<string[]> {
  const ak = '你的华为云AK';
  const sk = '你的华为云SK';
  const projectId = '你的华为云项目ID';
  const url = getHuaweiApiUrl(projectId, domain);

  // 生成华为云API签名(关键步骤,需实现sign函数)
  const { headers } = sign({
    method: 'GET',
    url,
    ak,
    sk,
    service: 'dns',
    region: 'cn-north-1' // 替换为你的服务区域
  });

  // 发起API请求
  const request = http.createHttp();
  const response = await request.request(url, {
    method: http.RequestMethod.GET,
    header: headers,
    responseType: http.ResponseType.JSON
  });

  // 解析响应(华为云返回格式:{ recordsets: [{ records: ['1.2.3.4', ...] }, ...] })
  const ips = response.result.recordsets?.[0]?.records as string[];
  if (!ips?.length) throw new Error('华为云解析失败');

  // 清除旧规则,注入新规则
  await connection.removeCustomDnsRule(domain).catch(() => {});
  await connection.addCustomDnsRule(domain, ips);
  return ips;
}

// 发起网络请求
export async function requestWithHuawei(url: string) {
  const urlObj = new URL(url);
  await resolveWithHuawei(urlObj.hostname);
  const request = http.createHttp();
  return request.request(url, { method: http.RequestMethod.GET });
}

备注 :华为云API需要签名认证,sign函数需实现HMAC-SHA256签名逻辑(参考华为云API签名文档),可封装为工具类复用。

(2)腾讯云HTTPDNS集成

腾讯云无官方鸿蒙SDK,需通过HTTPS接口直连,手动处理加密。

1. 开通服务与获取信息

登录腾讯云HTTPDNS控制台,开通服务。

typescript 复制代码
https://console.cloud.tencent.com/httpdns

获取授权ID (Account ID)和密钥(用于域名加密),添加需解析的域名。

2. 核心实现代码(含加密)
typescript 复制代码
import { http } from '@ohos.net.http';
import { connection } from '@ohos.net.connection';
import CryptoJS from 'crypto-js'; // 需通过ohpm安装crypto-js(处理AES加密)

// 腾讯云HTTPDNS接口:HTTPS加密入口
const TENCENT_HTTPDNS_URL = 'https://119.29.29.99/d';

// 域名加密(腾讯云要求dn参数需AES加密,密钥为控制台的"加密密钥")
function encryptDomain(domain: string, secretKey: string): string {
  const key = CryptoJS.enc.Utf8.parse(secretKey.padEnd(16, '0').slice(0, 16)); // 密钥需16位
  const encrypted = CryptoJS.AES.encrypt(domain, key, {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
  });
  return encrypted.ciphertext.toString(CryptoJS.enc.Hex).toUpperCase();
}

// 解析域名并设置DNS规则
export async function resolveWithTencent(domain: string): Promise<string[]> {
  const accountId = '你的腾讯云授权ID';
  const secretKey = '你的腾讯云密钥';
  const encryptedDomain = encryptDomain(domain, secretKey);

  // 发起HTTPS请求解析域名
  const request = http.createHttp();
  const response = await request.request(`${TENCENT_HTTPDNS_URL}?dn=${encryptedDomain}&id=${accountId}`, {
    method: http.RequestMethod.GET,
    responseType: http.ResponseType.JSON
  });

  // 解析响应(腾讯云返回格式:{ ips: ['1.2.3.4', ...] })
  const ips = response.result.ips as string[];
  if (!ips?.length) throw new Error('腾讯云解析失败');

  // 清除旧规则,注入新规则
  await connection.removeCustomDnsRule(domain).catch(() => {});
  await connection.addCustomDnsRule(domain, ips);
  return ips;
}

// 发起网络请求
export async function requestWithTencent(url: string) {
  const urlObj = new URL(url);
  await resolveWithTencent(urlObj.hostname);
  const request = http.createHttp();
  return request.request(url, { method: http.RequestMethod.GET });
}

(3)阿里云HTTPDNS集成

阿里云提供官方鸿蒙SDK,集成流程最简化。

1. 开通服务与获取信息

登录阿里云EMAS控制台,开通HTTPDNS服务。

typescript 复制代码
https://emas.console.aliyun.com/

在"域名管理"中添加需解析的域名,记录Account ID(控制台可查)。

2. 依赖安装
bash 复制代码
ohpm install @aliyun/httpdns  # 官方SDK
3. 核心实现代码
typescript 复制代码
import { httpdns, IpType } from '@aliyun/httpdns';
import { connection } from '@ohos.net.connection';
import { http } from '@ohos.net.http';
import Url from '@ohos.url';

// 初始化(在Ability的onCreate中调用)
export function initAliyunHttpDns(accountId: string, context: any) {
  httpdns.configService(accountId, { context }); // 传入账号ID和应用上下文
}

// 解析域名并设置DNS规则
export async function resolveWithAliyun(domain: string): Promise<string[]> {
  const accountId = '你的阿里云Account ID';
  const service = await httpdns.getService(accountId);
  // 解析域名,优先IPv4,无结果则返回IPv6
  const result = await service.getHttpDnsResultAsync(domain, IpType.Auto);
  
  // 清除旧规则,注入新规则
  await connection.removeCustomDnsRule(domain).catch(() => {}); // 忽略清除失败
  if (result.ipv4s?.length) {
    await connection.addCustomDnsRule(domain, result.ipv4s);
    return result.ipv4s;
  } else if (result.ipv6s?.length) {
    await connection.addCustomDnsRule(domain, result.ipv6s);
    return result.ipv6s;
  }
  throw new Error('阿里云解析失败');
}

// 发起网络请求(自动使用绑定的IP)
export async function requestWithAliyun(url: string) {
  const urlObj = Url.URL.parseURL(url);
  await resolveWithAliyun(urlObj.hostname); // 解析并绑定域名
  const request = http.createHttp();
  return request.request(url, { method: http.RequestMethod.GET });
}

五、统一工具类封装(多厂商切换)

为简化调用,封装一个通用工具类,支持动态切换阿里云、腾讯云、华为云:

typescript 复制代码
// HttpDnsManager.ts
export enum DnsProvider {
  ALIYUN = 'aliyun',
  TENCENT = 'tencent',
  HUAWEI = 'huawei'
}

export class HttpDnsManager {
  private provider: DnsProvider;
  private config: { [key: string]: any }; // 存储各厂商的配置(如accountId、密钥等)

  constructor(provider: DnsProvider, config: { [key: string]: any }) {
    this.provider = provider;
    this.config = config;
  }

  // 初始化(仅阿里云需要)
  init(context: any) {
    if (this.provider === DnsProvider.ALIYUN) {
      import('@aliyun/httpdns').then(({ httpdns }) => {
        httpdns.configService(this.config.accountId, { context });
      });
    }
  }

  // 解析域名并设置规则
  async resolve(domain: string): Promise<string[]> {
    switch (this.provider) {
      case DnsProvider.ALIYUN:
        const aliyun = await import('./aliyun');
        return aliyun.resolveWithAliyun(domain);
      case DnsProvider.TENCENT:
        const tencent = await import('./tencent');
        return tencent.resolveWithTencent(domain);
      case DnsProvider.HUAWEI:
        const huawei = await import('./huawei');
        return huawei.resolveWithHuawei(domain);
      default:
        throw new Error('未知服务商');
    }
  }

  // 发起网络请求
  async request(url: string) {
    const urlObj = new URL(url);
    await this.resolve(urlObj.hostname);
    const { http } = await import('@ohos.net.http');
    const request = http.createHttp();
    return request.request(url, { method: http.RequestMethod.GET });
  }
}

// 使用示例
const dnsManager = new HttpDnsManager(DnsProvider.ALIYUN, {
  accountId: '你的阿里云Account ID'
});
// 在Ability onCreate中初始化
// dnsManager.init(this.context);
// 发起请求
// dnsManager.request('https://www.example.com');

六、服务商差异对比

维度 阿里云 腾讯云 华为云
接入难度 低(官方SDK) 中(需手动加密) 高(需实现API签名)
核心认证信息 Account ID 授权ID + 加密密钥 AK + SK + 项目ID
解析接口 SDK方法getHttpDnsResultAsync HTTPS接口https://119.29.29.99/d 云解析API v2/recordsets
优势 集成简单,兼容性好 解析速度快,支持加密传输 与华为云生态联动性强

七、注意事项

1、回退机制:解析失败时(如网络异常),需回退到系统默认DNS解析,避免阻断业务:

typescript 复制代码
async function safeResolve(domain: string) {
  try {
    return await dnsManager.resolve(domain);
  } catch (e) {
    console.error('HTTPDNS解析失败,使用系统DNS');
    return []; // 空数组表示不设置规则,走系统默认
  }
}

2、规则有效期addCustomDnsRule设置的规则在应用进程内生效,重启后需重新初始化。
3、加密与签名 :腾讯云的域名加密和华为云的API签名需严格按照官方文档实现,否则会解析失败。
5、厂商切换 :通过HttpDnsManagerprovider参数可动态切换服务商,无需修改业务代码。

相关推荐
nanchen22515 小时前
从混沌到有序:揭秘团购鸿蒙高内聚、可扩展的现代化前端架构
harmonyos
长弓三石6 小时前
鸿蒙网络编程系列59-仓颉版TLS回声服务器示例
harmonyos·鸿蒙·tls·仓颉
yrjw8 小时前
一款基于 ReactNative 最新发布的`Android/iOS` 新架构文档预览开源库
harmonyos
ajassi20009 小时前
开源 Arkts 鸿蒙应用 开发(十三)音频--MP3播放
linux·华为·开源·harmonyos
zhanshuo20 小时前
让鸿蒙应用丝滑如飞:绘图性能优化全攻略(附代码实战)
harmonyos
zhanshuo20 小时前
适配鸿蒙低性能设备的终极优化方案:从启动到渲染全链路实战
harmonyos
Georgewu21 小时前
【HarmonyOS】鸿蒙ArkWeb加载优化方案详解
harmonyos
simple_lau1 天前
鸿蒙 3D 开发实战:从模型加载到动画管理的完整实现
harmonyos·arkts·arkui
litongde1 天前
React Native 编程
react native·harmonyos