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
相关产品推荐
相关产品推荐

