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

如何阻止WKWebView跳转至关联的外部App?

解决方案

核心逻辑

系统会优先将已配置Universal Links的域名链接导向关联App,要实现强制在自身WebView内加载,需在导航决策阶段拦截这类跳转请求,将其转为普通HTTP/HTTPS请求处理。

具体实现

1. 拦截Universal Links跳转(WKNavigationDelegate实现)

通过decidePolicyFor navigationAction方法识别并修改跳转请求:

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    guard let requestUrl = navigationAction.request.url else {
        decisionHandler(.allow)
        return
    }
    
    // 系统处理Universal Links时会将scheme转为applinks,需还原为https
    if requestUrl.scheme == "applinks" {
        if let originalHttpsUrl = URL(string: requestUrl.absoluteString.replacingOccurrences(of: "applinks://", with: "https://")) {
            decisionHandler(.cancel)
            webView.load(URLRequest(url: originalHttpsUrl))
            return
        }
    }
    
    decisionHandler(.allow)
}

2. 补充拦截网页内JS触发的跳转

部分网页通过JavaScript发起跳转,可配合WKUserScript主动拦截:

// 初始化WKWebView时注入脚本
let linkInterceptScript = WKUserScript(source: """
window.addEventListener('click', function(e) {
    let target = e.target;
    while (target && target.tagName !== 'A') {
        target = target.parentNode;
    }
    if (target && target.href) {
        e.preventDefault();
        window.webkit.messageHandlers.linkInterceptor.postMessage(target.href);
    }
}, true);
""", injectionTime: .atDocumentEnd, forMainFrameOnly: true)

let contentController = WKUserContentController()
contentController.addUserScript(linkInterceptScript)
contentController.add(self, name: "linkInterceptor")

let webConfig = WKWebViewConfiguration()
webConfig.userContentController = contentController

let webView = WKWebView(frame: .zero, configuration: webConfig)
webView.navigationDelegate = self

实现WKScriptMessageHandler处理脚本消息:

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    guard let urlStr = message.body as? String, let targetUrl = URL(string: urlStr) else { return }
    webView.load(URLRequest(url: targetUrl))
}

注意事项

  • 确保自身App未注册目标域名的Universal Links,避免系统优先触发自身跳转
  • 测试时需确认目标关联App已安装,验证拦截逻辑是否生效
  • 复杂链接需检查参数完整性,保证还原后的请求与原链接一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 11:05:07