@mogody/react-native-tencent-httpdns
@mogody/react-native-tencent-httpdns 为 React Native 应用接入腾讯云 HTTPDNS。它只改造 React Native 的原生 HTTP 网络层,让 fetch、XHR、axios、apisauce 等仍然使用带域名的 URL,同时在 Android/iOS 原生侧对指定域名走腾讯 HTTPDNS 解析。
包内支持腾讯 HTTPDNS 的三种查询模式:HTTPS、HTTP AES 加密、HTTP DES 加密。默认并推荐使用 HTTPS 模式。
安装
yarn add @mogody/react-native-tencent-httpdns
iOS 安装 Pods:
bundle exec pod install
启动时机
必须在 App 启动阶段尽早调用 install,并且要早于第一次 React Native 网络请求。
这里的网络请求包括 fetch、XHR、axios、apisauce,以及任何最终走 React Native HTTP 网络层的请求。Android 需要在 React Native 创建共享 OkHttpClient 之前注入 DNS;iOS 需要在 React Native 创建 URLSession 之前设置 URLSession 配置提供者。
生产接入推荐优先使用原生启动期 API:Android 调用 TencentHttpDNS.installFromManifest(this),iOS 调用 MGTencentHttpDNSInstaller.installFromMainBundle()。JS install 仍可用于能保证调用足够早的场景。
不要把 JS URL 替换成 IP
JavaScript 侧的请求 URL 必须继续使用域名:
await fetch('https://api.example.com/v1/profile');
不要改成 IP,也不要在 JS 请求层手动拼 IP:
// 不要这样做
await fetch('https://203.0.113.10/v1/profile');
保持域名可以让 TLS 证书、SNI、Host、Cookie、重定向和原生 HTTPDNS 域名匹配都按预期工作。
hosts 白名单
hosts 是 HTTPDNS 域名白名单,只填写主机名,不包含协议、路径或端口。
hosts: ['api.example.com', 'static.example.com']
只有白名单内的域名会尝试使用腾讯 HTTPDNS;未列入 hosts 的域名会继续使用系统 DNS。建议只加入自己可控、已经在腾讯 HTTPDNS 后台配置好的业务域名。
支持的模式
channel |
凭据 | Android SDK 调用 | iOS encryptType |
说明 |
|---|---|---|---|---|
https |
token |
https() |
2 |
HTTPS 查询模式,默认值,推荐用于公开项目和默认接入。 |
aes |
dnsKey |
aesHttp() |
1 |
基于 HTTP 的 AES 加密查询模式。 |
des |
dnsKey |
desHttp() |
0 |
基于 HTTP 的 DES 加密查询模式。 |
省略 channel 时等同于 channel: 'https'。
用法示例
HTTPS 模式
import TencentHttpDNS from '@mogody/react-native-tencent-httpdns';
const result = await TencentHttpDNS.install({
enabled: true,
channel: 'https',
dnsId: 'your-dns-id',
token: 'your-https-token',
hosts: ['api.example.com'],
timeoutMs: 2000,
});
HTTPS 默认模式
import TencentHttpDNS from '@mogody/react-native-tencent-httpdns';
await TencentHttpDNS.install({
dnsId: 'your-dns-id',
token: 'your-https-token',
hosts: ['api.example.com'],
});
AES 模式
import TencentHttpDNS from '@mogody/react-native-tencent-httpdns';
await TencentHttpDNS.install({
channel: 'aes',
dnsId: 'your-dns-id',
dnsKey: 'your-dns-key',
hosts: ['api.example.com'],
});
DES 模式
import TencentHttpDNS from '@mogody/react-native-tencent-httpdns';
await TencentHttpDNS.install({
channel: 'des',
dnsId: 'your-dns-id',
dnsKey: 'your-dns-key',
hosts: ['api.example.com'],
});
禁用模式
import TencentHttpDNS from '@mogody/react-native-tencent-httpdns';
await TencentHttpDNS.install({ enabled: false });
禁用模式不需要 dnsId、token、dnsKey、channel 或 hosts,也不会调用原生安装逻辑。返回结果会包含 installed: false 和 reason: 'disabled'。
Android 原生启动期安装
Android 如果需要抢在 React Native 共享 OkHttpClient 创建前安装 HTTPDNS,可以在 MainApplication.onCreate() 里调用包提供的原生 API:
import com.mogody.tencenthttpdns.TencentHttpDNS
override fun onCreate() {
super.onCreate()
TencentHttpDNS.installFromManifest(this)
loadReactNative(this)
}
配置值由宿主 App 的 android/gradle.properties 提供,包内 AndroidManifest 会通过 manifest placeholders 合并成 meta-data:
TENCENT_HTTPDNS_CHANNEL=https
TENCENT_HTTPDNS_DNS_ID=your-dns-id
TENCENT_HTTPDNS_HTTPS_TOKEN=your-https-token
TENCENT_HTTPDNS_AES_KEY=your-aes-key
TENCENT_HTTPDNS_DES_KEY=your-des-key
TENCENT_HTTPDNS_HOSTS=api.example.com,static.example.com
TENCENT_HTTPDNS_CHANNEL 支持 https、aes、des。https 使用 TENCENT_HTTPDNS_HTTPS_TOKEN,aes 使用 TENCENT_HTTPDNS_AES_KEY,des 使用 TENCENT_HTTPDNS_DES_KEY。
iOS 原生启动期安装
iOS 如果需要抢在 React Native 创建 URLSession 前安装 HTTPDNS,可以在 AppDelegate.swift 里调用包提供的原生 API:
window = UIWindow(frame: UIScreen.main.bounds)
MGTencentHttpDNSInstaller.installFromMainBundle()
factory.startReactNative(
withModuleName: "YourApp",
in: window,
launchOptions: launchOptions
)
Swift 工程需要在 bridging header 中导入 installer:
#import <MogodyTencentHttpDNS/MGTencentHttpDNSInstaller.h>
配置值由宿主 App 的 Info.plist 提供。建议把敏感值写成 Xcode Build Settings 占位符,再由本地或 CI 注入:
<key>TencentHTTPDNSChannel</key>
<string>https</string>
<key>TencentHTTPDNSDebug</key>
<false/>
<key>TencentHTTPDNSDnsId</key>
<string>$(TENCENT_HTTPDNS_DNS_ID)</string>
<key>TencentHTTPDNSHosts</key>
<string>api.example.com,static.example.com</string>
<key>TencentHTTPDNSHttpsToken</key>
<string>$(TENCENT_HTTPDNS_HTTPS_TOKEN)</string>
installFromMainBundle() 会默认使用 channel=https、timeoutMs=2000、debug=false、useExpiredIp=false、persistentCache=true、bypassWhenProxy=true。如果 $(...) 占位符没有被 Xcode 替换,包内会把它视为空值并输出 HTTPDNS install skipped: missing bundle config。
install 返回值
install 返回:
type TencentHttpDNSInstallResult = {
installed: boolean;
reason?: string;
hosts: string[];
platform: string;
};
已知的非异常原因:
reason |
平台 | 含义 |
|---|---|---|
disabled |
JS | 调用了 { enabled: false },未执行原生安装。 |
okhttp-client-already-created |
Android | install 调用太晚,React Native 已缓存的共享 OkHttpClient 已经创建,现有客户端不会使用新 DNS。部分 React Native 版本会创建未缓存的 context client,因此 Android 生产接入应优先使用原生启动期安装。 |
proxy-detected |
iOS | bypassWhenProxy 为 true 且检测到 HTTP、HTTPS 或 SOCKS 代理,已绕过 HTTPDNS。 |
installed: false 不一定代表抛错;请同时检查 reason。
Options
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
enabled |
boolean |
否 | true |
设置为 false 时进入禁用模式,不需要凭据、模式或域名。 |
channel |
'https' | 'aes' | 'des' |
否 | 'https' |
腾讯 HTTPDNS 查询模式。 |
dnsId |
string |
启用时必填 | 无 | 腾讯云 HTTPDNS 授权 ID。 |
token |
string |
channel: 'https' 时必填 |
无 | HTTPS 模式使用的腾讯 HTTPDNS token。 |
dnsKey |
string |
channel: 'aes' 或 'des' 时必填 |
无 | AES/DES 模式使用的腾讯 HTTPDNS key。 |
hosts |
string[] |
启用时必填 | 无 | HTTPDNS 域名白名单,只写 hostname。 |
timeoutMs |
number |
否 | 2000 |
腾讯 SDK 查询超时时间,单位毫秒。 |
debug |
boolean |
否 | false |
启用原生 SDK 调试日志。 |
useExpiredIp |
boolean |
否 | false |
允许腾讯 SDK 使用过期 IP 缓存。 |
persistentCache |
boolean |
否 | true |
启用腾讯 SDK 持久化 IP 缓存。 |
bypassWhenProxy |
boolean |
否 | true |
检测到本地代理时绕过 HTTPDNS,便于抓包和调试。 |
Android 注意事项
Android 使用腾讯 io.github.dnspod:httpdns-sdk:4.11.0,并通过 React Native 的 OkHttpClientProvider 注入自定义 OkHttp provider。
安装后,React Native 共享 OkHttpClient 的 Dns 会先检查 hosts 白名单:白名单内域名使用 MSDKDnsResolver 查询,未命中的域名回退到 Dns.SYSTEM。因此 JS URL 仍要保持域名形式,且只有 hosts 中的域名会被 HTTPDNS 处理。
Android 生产接入建议使用 MainApplication.onCreate() 中的 TencentHttpDNS.installFromManifest(this),并确保它早于 loadReactNative(this)。JS install 仍可用于配置较早的场景,但如果 React Native 已经创建网络模块或 context-specific OkHttpClient,已有客户端不会 retroactively 使用新 DNS,且部分 React Native 版本无法可靠检测这种状态。
如果 install 调用太晚且 React Native 已经创建可检测的共享 OkHttpClient,Android 会返回 installed: false,reason: 'okhttp-client-already-created'。此时已有客户端不会受本次安装影响,请把安装前移到原生启动期。
aes 和 des 是基于 HTTP 的加密查询模式。Android 9+ 及应用自定义 Network Security Config 可能限制明文 HTTP;如果必须使用 AES/DES,请确认应用的 cleartext traffic 策略允许腾讯 HTTPDNS SDK 的 HTTP 查询通道。默认推荐 https 模式以避免明文通道配置。
iOS 注意事项
iOS 使用 MSDKDns_C11 和 MSDKDnsHttpMessageTools,并通过 RCTSetCustomNSURLSessionConfigurationProvider 为 React Native 的 URLSession 注入 HTTPDNS 处理能力。
生产接入建议在 AppDelegate 中、factory.startReactNative(...) 前调用 MGTencentHttpDNSInstaller.installFromMainBundle()。JS install 仍可用于能保证足够早调用的场景,但如果 URLSession 已经创建,旧 session 不会 retroactively 应用新的 HTTPDNS 配置。
安装时会调用腾讯 SDK 的域名劫持白名单配置,例如 WGSetHijackDomainArray(hosts),只有 hosts 中的域名会被 HTTPDNS 处理。请继续在 JS 请求里使用域名,不要改成 IP。
如果 bypassWhenProxy 为 true 且系统检测到 HTTP、HTTPS 或 SOCKS 代理,iOS 会返回 installed: false,reason: 'proxy-detected',并绕过 HTTPDNS,方便调试代理和抓包场景。
aes 和 des 是基于 HTTP 的加密查询模式,可能受到 iOS ATS 明文 HTTP 限制影响。如果必须使用 AES/DES,请按应用安全策略为腾讯 HTTPDNS 查询通道配置 ATS 例外;默认推荐 https 模式。
清理缓存
清理指定域名缓存:
import TencentHttpDNS from '@mogody/react-native-tencent-httpdns';
await TencentHttpDNS.clearCache(['api.example.com']);
不传参数会尝试清理原生 SDK 支持范围内的全部 HTTPDNS 缓存:
await TencentHttpDNS.clearCache();
作用范围限制
本包只影响 React Native HTTP 网络层。
它不会自动覆盖 WebView、AVPlayer、TrackPlayer、CDN 图片加载器、上传 SDK、原生第三方 SDK 自己发起的网络请求,也不覆盖 WebSocket。若这些模块也需要 HTTPDNS,需要分别接入对应模块或 SDK 的 DNS/网络配置能力。
接入文档
宿主 App 接入说明见 docs/consumer/zh-CN.md。
安全建议
不要把 dnsId、token、dnsKey 提交到源码仓库。安全配置、CI Secret、原生构建配置或运行时配置注入可以让凭据不进入源码控制,但如果这些值被打进移动端包内,仍会随分发的 App 二进制一起交付,不能视为对终端用户保密。
公开项目和默认接入场景建议优先使用 https 模式。只有在腾讯 HTTPDNS 后台配置、业务兼容性和平台明文策略都确认后,才使用 aes 或 des 模式。