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

如何在WKWebView中拦截链接点击并按需处理跳转?

如何在WKWebView中精准拦截用户触发的链接点击

你提到的问题确实很常见——用decidePolicyForNavigationAction拦截导航时,总会被页面里的追踪脚本、自动广告请求这类非用户主动操作触发,导致判断逻辑被干扰。下面我分享一个精准区分用户点击和自动请求的方案:

核心思路:通过导航类型和来源框架过滤请求

WKNavigationAction里有两个关键属性可以帮我们筛选出真正的用户点击:

  • navigationType:标记导航的触发方式,我们只关心.linkActivated(用户点击链接)这类主动操作的类型
  • sourceFrame:通过isMainFrame判断请求是否来自主页面,避免iframe里的广告、追踪链接干扰判断

具体实现代码(Swift)

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    // 先过滤掉非用户主动触发的请求,以及非主框架的请求
    guard let targetURL = navigationAction.request.url,
          navigationAction.navigationType == .linkActivated, // 仅限用户点击链接
          navigationAction.sourceFrame.isMainFrame else { // 仅限主页面的请求
        // 其他情况(比如脚本自动请求、iframe跳转)允许正常加载
        decisionHandler(.allow)
        return
    }
    
    // 这里根据你的业务规则判断是外部打开还是内部加载
    if shouldOpenExternally(targetURL) {
        // 调用系统浏览器打开链接
        if UIApplication.shared.canOpenURL(targetURL) {
            UIApplication.shared.open(targetURL)
        }
        // 取消WebView内部的加载
        decisionHandler(.cancel)
    } else {
        // 允许在WebView内正常加载
        decisionHandler(.allow)
    }
}

// 自定义判断逻辑:示例为非本站域名的链接外部打开
private func shouldOpenExternally(_ url: URL) -> Bool {
    let allowedDomains = ["your-app-domain.com", "trust-domain.com"]
    return !(allowedDomains.contains { url.host?.contains($0) ?? false })
}

补充说明

  • 如果你的页面存在JS模拟点击的场景(这类请求的navigationType会是.other),可以在判断条件里额外加入URL规则的校验,比如检查是否是常见的跳转域名,结合业务调整过滤逻辑。
  • 务必记得调用decisionHandler——无论你选择允许还是取消导航,必须调用这个闭包,否则会导致WebView卡住。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:12:33