Swift WKWebView访问白名单站点仍弹出拦截告警问题如何解决
问题原因
- 未区分主帧导航和子资源/子帧请求:现有代码会拦截webView发出的所有请求,包括白名单网站内部加载的广告、统计脚本、静态资源等第三方域名请求。这类第三方请求不在白名单内时会触发拦截逻辑,弹出提示,让你误以为是主站被拦截,实际上主站本身已经被允许加载。
- 弹窗触发逻辑无限制:所有被拦截的请求无论类型都会触发弹窗,正常访问白名单网站时只要页面存在第三方资源请求,就会反复弹出拦截提示。
- 原域名匹配逻辑存在安全隐患:使用
contains匹配可能被恶意域名绕过,比如构造smithsonianmag.com.evil.com这类域名,host包含白名单域名也会被放行。
修复方案
优化判断逻辑,仅对用户主动访问的主页面导航做拦截提示,同时优化域名匹配规则,修复后的代码如下:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { guard let url = navigationAction.request.url, let host = url.host else { decisionHandler(.cancel) return } // 仅主页面导航被拦截时才弹出提示 let isMainFrameNavigation = navigationAction.targetFrame?.isMainFrame ?? false // 统一去掉host的www前缀,兼容带www的域名场景 let cleanedHost = host.hasPrefix("www.") ? String(host.dropFirst(4)) : host // 用后缀匹配替代包含匹配,避免恶意域名绕过 for website in websites { if cleanedHost == website || cleanedHost.hasSuffix("." + website) { decisionHandler(.allow) return } } decisionHandler(.cancel) if isMainFrameNavigation { let ac = UIAlertController(title: "你尝试访问的网站不在允许列表中", message: nil, preferredStyle: .alert) ac.addAction(UIAlertAction(title: "取消", style: .cancel)) present(ac, animated: true) } }
测试逻辑说明
你的Playground测试仅验证了直接构造白名单域名URL时host提取正常,没有模拟真实网站加载时会发起大量第三方请求的场景,因此无法复现实际运行时的问题。
内容的提问来源于stack exchange,提问作者Giovanna
相关产品推荐
相关产品推荐

