You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter WebView应用如何将DNS地址修改为1.1.1.1?

WebView 强制使用 1.1.1.1 DNS 的解决方案

Android 平台实现方案

  • 核心思路:通过拦截 WebView 请求,手动用 1.1.1.1 解析域名,替换请求地址并补充 Host 头,避免服务器域名验证失败。
  • 关键代码示例:
webView.setWebViewClient(new WebViewClient() {
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        String url = request.getUrl().toString();
        Uri uri = Uri.parse(url);
        String host = uri.getHost();
        if (host == null) return super.shouldInterceptRequest(view, request);

        // 用1.1.1.1解析域名(需依赖第三方DNS库,如dnsjava)
        String targetIp = resolveWithCloudflareDNS(host);
        if (targetIp == null) return super.shouldInterceptRequest(view, request);

        // 替换URL中的主机为解析后的IP
        String modifiedUrl = url.replaceFirst(host, targetIp);
        Map<String, String> headers = new HashMap<>();
        headers.put("Host", host);

        try {
            URLConnection conn = new URL(modifiedUrl).openConnection();
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                conn.setRequestProperty(entry.getKey(), entry.getValue());
            }
            return new WebResourceResponse(
                    conn.getContentType(),
                    conn.getContentEncoding(),
                    conn.getInputStream()
            );
        } catch (IOException e) {
            e.printStackTrace();
            return super.shouldInterceptRequest(view, request);
        }
    }

    private String resolveWithCloudflareDNS(String host) {
        // 使用dnsjava库指定1.1.1.1作为DNS服务器
        try {
            SimpleResolver resolver = new SimpleResolver("1.1.1.1");
            Record[] records = resolver.resolve(new Name(host), Type.A);
            if (records != null && records.length > 0) {
                return ((ARecord) records[0]).getAddress().getHostAddress();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
});
  • 注意事项:原生Android API无法直接指定DNS服务器,必须依赖第三方库;HTTPS请求需处理证书域名不匹配问题,生产环境建议通过自定义证书验证逻辑规避,而非简单跳过验证。

iOS 平台实现方案

  • 核心思路:利用 WKWebView 的自定义 Scheme 处理器,拦截 HTTP/HTTPS 请求,通过第三方DNS库用1.1.1.1解析域名后重新发起请求。
  • 关键代码示例:
class CloudflareDNSHandler: NSObject, WKURLSchemeHandler {
    func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
        guard let url = urlSchemeTask.request.url, let host = url.host else {
            urlSchemeTask.didFailWithError(NSError(domain: "DNSHandler", code: -1, userInfo: [NSLocalizedDescriptionKey: "无效URL"]))
            return
        }

        resolveHostWithCloudflare(host) { ip in
            guard let targetIp = ip else {
                urlSchemeTask.didFailWithError(NSError(domain: "DNSHandler", code: -2, userInfo: [NSLocalizedDescriptionKey: "DNS解析失败"]))
                return
            }

            // 构造替换IP后的新请求
            var components = URLComponents(url: url, resolvingAgainstBaseURL: false)
            components?.host = targetIp
            guard let modifiedUrl = components?.url else {
                urlSchemeTask.didFailWithError(NSError(domain: "DNSHandler", code: -3, userInfo: [NSLocalizedDescriptionKey: "构造新URL失败"]))
                return
            }

            var newRequest = URLRequest(url: modifiedUrl)
            newRequest.setValue(host, forHTTPHeaderField: "Host")

            let task = URLSession.shared.dataTask(with: newRequest) { data, response, error in
                if let error = error {
                    urlSchemeTask.didFailWithError(error)
                    return
                }
                guard let httpResp = response as? HTTPURLResponse, let data = data else {
                    urlSchemeTask.didFailWithError(NSError(domain: "DNSHandler", code: -4, userInfo: [NSLocalizedDescriptionKey: "无响应数据"]))
                    return
                }
                urlSchemeTask.didReceive(httpResp)
                urlSchemeTask.didReceive(data)
                urlSchemeTask.didFinish()
            }
            task.resume()
        }
    }

    private func resolveHostWithCloudflare(_ host: String, completion: @escaping (String?) -> Void) {
        // 使用第三方DNS库(如DNSService)指定1.1.1.1解析
        let resolver = DNSServiceResolver(server: "1.1.1.1")
        resolver.resolve(host, recordType: .A) { result in
            switch result {
            case .success(let records):
                completion((records.first as? DNSARecord)?.address)
            case .failure:
                completion(nil)
            }
        }
    }

    func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {
        // 实现请求中断逻辑
    }
}

// 注册处理器到WKWebView
let config = WKWebViewConfiguration()
config.setURLSchemeHandler(CloudflareDNSHandler(), forURLScheme: "http")
config.setURLSchemeHandler(CloudflareDNSHandler(), forURLScheme: "https")
let webView = WKWebView(frame: .zero, configuration: config)
  • 注意事项:iOS原生API不支持指定DNS服务器,必须依赖第三方库;HTTPS请求需自定义URLSession的信任评估逻辑,处理IP与证书域名不匹配的问题。

备选方案:基于VPN/代理的全局DNS配置

如果上述拦截方案无法满足需求,可通过应用内VPN(如Android的VpnService、iOS的NEVPNManager)将应用流量导向使用1.1.1.1作为DNS的代理服务器。这种方式无需修改WebView请求逻辑,但需要用户授权VPN权限,实现复杂度较高。

内容的提问来源于stack exchange,提问作者Baatar Ganzorig

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 02:35:00