全部產品
Search
文件中心

HTTPDNS:鴻蒙應用接入DoH

更新時間:Sep 09, 2025

本文檔介紹如何在 HarmonyOS 原生網路程式庫、RCP 和 webiew 中通過DoH,接入HTTPDNS。

1. 前言

在 HarmonyOS 平台,推薦您優先通過HarmonyOS SDK手冊。若您由於某些原因無法引入 SDK,您可以通過 DoH的接入,本文聚焦 HarmonyOS 下“網路程式庫或組件”的 DoH接入方式,涵蓋:

說明
  • 鴻蒙的網路組件只支援配置一個 DoH 連結,為提高業務穩定性,建議做好Local DNS降級

    • Network Kit 和 RCP 庫中,不支援配置自動降級到 Local DNS 的模式,請做好應用側降級,參考接入方案的範例程式碼。

    • ArkWeb 可以通過設定SecureDnsModeAUTO開啟允許自動降級到 Local DNS。

  • Network Kit 和 RCP 的 DoH 配置會受addCustomDnsRule自訂解析規則的影響,如果您通過addCustomDnsRule配置了某些網域名稱的解析,那麼該網域名稱將不會再通過DoH 解析。

2. 前提條件

通過 DoH 接入 HarmonyOS 下“網路程式庫或組件”前,請您確保已經完成配置DoH服務

3. Network Kit(httpRequest)接入 DoH

通過 Network Kit 在單次請求上指定http.request(options: http.RequestOptions)中的options.dnsOverHttps: string為您的 DoH 存取點,即可開啟 DoH,無需改造全域會話。範例程式碼如下:

import http from '@ohos.net.http'; 
const httpRequest: http.HttpRequest = http.createHttp();
 // 這裡請替換為您自己的 DoH URL
const DOH_ENDPOINT = 'https://xxxxx.aliyunhttpdns.com/dns-query';

const isDoHFailure = (err: ErrorDetails): boolean => {
  const code = String(err.code ?? '');
  const msg = String(err.message ?? '');
  return /(couldn'?t\s+resolve\s+host\s+name|resolve\s+host\s+name|dns|resolve|name\s*not\s*resolved|EAI_AGAIN)/i.test(msg) || /DNS/i.test(code);
};

httpRequest.request(this.urlInput, {
  method: http.RequestMethod.GET,
  connectTimeout: 3000,
  readTimeout: 3000,
  dnsOverHttps: DOH_ENDPOINT,
}).then((res: http.HttpResponse) => {
  console.log('DoH request success:', res);
}).catch((err: ErrorDetails) => {
  if (isDoHFailure(err)) {
    console.error('DoH request error, falling back to local DNS:', err);
    httpRequest.request(this.urlInput, {
      method: http.RequestMethod.GET,
      connectTimeout: 3000,
      readTimeout: 3000,
    }).then((fallbackRes: http.HttpResponse) => {
      console.log('Fallback request success:', fallbackRes);
    }).catch((fallbackErr: ErrorDetails) => {
      console.error('Fallback request error:', fallbackErr);
    });
  } else {
    console.error('Request error:', err);
  }
});

4. Remote Communication Kit(RCP)接入 DoH

RCP 網路程式庫支援在全域 Session 和 單個 Request 兩個不同粒度下接入 DoH, 下面介紹對應的接入方式。

4.1 Session 接入 DoH

通過 RCP 在會話層面上指定SessionConfiguration.requestConfiguration.dns.dnsOverHttps為您的 DoH 存取點,即可開啟 DoH,無需改造全域會話。範例程式碼如下:

import { rcp } from '@kit.RemoteCommunicationKit';
import type { BusinessError } from '@ohos.base';
private isDoHFailure(err: BusinessError): boolean {
    const code: string = err.code ? String(err.code) : '';
    const msg: string =  String(err.data);
    return /(couldn'?t\s+resolve\s+host\s+name|resolve\s+host\s+name|dns|resolve|name\s*not\s*resolved|EAI_AGAIN)/i.test(msg) || /DNS/i.test(code);
  }
  
 async sendRequest() {
    try {
      const dohConfig: rcp.DnsOverHttpsConfiguration = {
        url: 'https://xxxxx.aliyunhttpdns.com/dns-query',
        skipCertificatesValidation: false,
      };

      const dohSession = rcp.createSession({
        requestConfiguration: {
          dns: { dnsOverHttps: dohConfig },
          transfer: { timeout: { connectMs: 3000, transferMs: 8000 } },
        },
      });

      const resp = await dohSession.get(this.urlInput);
      console.info('DoH request success, status=', resp.statusCode);
      console.info('Response:', JSON.stringify(resp));
    } catch (err) {
      if (this.isDoHFailure(err)) {
        console.error('DoH request error, falling back to local DNS:', err);
        try {
          const localSession = rcp.createSession({
            requestConfiguration: { transfer: { timeout: { connectMs: 3000, transferMs: 8000 } } },
          });
          const fb = await localSession.get(this.urlInput);
          console.info('Fallback (local DNS) success, status=', fb.statusCode);
          console.info('Fallback response:', JSON.stringify(fb));
        } catch (fallbackErr) {
          console.error('Fallback (local DNS) request error:', fallbackErr);
        }
      } else {
        console.error('Request error (non-DoH):', err);
      }
    }
  }

4.2 Request 接入 DoH

通過 RCP 在單次請求上指定 request.configuration.dns.dnsOverHttps為您的 DoH 存取點,即可開啟 DoH,無需改造全域會話。範例程式碼如下:

import { rcp } from '@kit.RemoteCommunicationKit';
import type { BusinessError } from '@ohos.base';


  async sendRequest() {
    try {
      const dohConfig: rcp.DnsOverHttpsConfiguration = {
        url: 'https://xxxxx.aliyunhttpdns.com/dns-query',
        skipCertificatesValidation: false,
      };

      const session = rcp.createSession({
        requestConfiguration: {
          transfer: { timeout: { connectMs: 3000, transferMs: 8000 } },
        },
      });

      const perReq = new rcp.Request(this.urlInput, 'GET', undefined, undefined, undefined, undefined, {
        dns: { dnsOverHttps: dohConfig },
      });

      const resp = await session.fetch(perReq);
      console.info('DoH request success, status=', resp.statusCode);
      console.info('Response:', JSON.stringify(resp));
    } catch (err) {
      if (this.isDoHFailure(err)) {
        console.error('DoH request error, falling back to local DNS:', err);
        try {
          const localSession = rcp.createSession({
            requestConfiguration: { transfer: { timeout: { connectMs: 3000, transferMs: 8000 } } },
          });
          const fb = await localSession.get(this.urlInput);
          console.info('Fallback (local DNS) success, status=', fb.statusCode);
          console.info('Fallback response:', JSON.stringify(fb));
        } catch (fallbackErr) {
          console.error('Fallback (local DNS) request error:', fallbackErr);
        }
      } else {
        console.error('Request error (non-DoH):', err);
      }
    }
  }

5. WebView 的 DoH 策略

通過 webview.WebviewController.setHttpDns指定您的 DoH URL,範例程式碼如下:

import { webview } from '@kit.ArkWeb';
webview.WebviewController.setHttpDns(webview.SecureDnsMode.AUTO, 'https://xxxxx.aliyunhttpdns.com/dns-query');
說明

鴻蒙的網路組件只支援配置一個 DoH 連結,為提高業務穩定性,建議做好Local DNS降級,ArkWeb 可以通過設定SecureDnsModeAUTO開啟允許自動降級到 Local DNS。

6. 總結

通過本文檔介紹的步驟,您可以成功在 鴻蒙網路程式庫中整合DNS over HTTPS (DoH)功能,從而顯著提升應用程式的安全性和使用者隱私保護能力。配置後可通過將手機 WIFI 網路的 DNS 伺服器設定為一個無效地址,觀察業務請求是否依然能夠正常發起,以此判斷 DoH 是否接入成功。