WKWebView调用JavaScript的window.open后打开空白页问题
解决WKWebView处理延迟跳转的空白页问题
问题核心
你碰到的问题本质是:window.open('', '_blank') 创建的空白窗口,WKWebView 必须通过 WKUIDelegate 提供对应的 WebView 实例,否则无法处理后续的 location.href 跳转;同时延迟触发的跳转请求需要通过导航代理来捕获和允许。
解决步骤
实现WKUIDelegate的新窗口创建方法
window.open会调用该方法请求新的 WebView 实例,不实现的话新窗口会默认显示空白,且无法响应后续跳转。为新WebView绑定导航代理
确保新创建的 WebView 关联WKNavigationDelegate,这样才能捕获到延迟的location.href跳转请求。
完整代码示例
import WebKit class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate { var webView: WKWebView! override func viewDidLoad() { super.viewDidLoad() let config = WKWebViewConfiguration() webView = WKWebView(frame: view.bounds, configuration: config) webView.uiDelegate = self webView.navigationDelegate = self view.addSubview(webView) // 加载目标HTML内容 let htmlString = """ <div><a href="javascript:wopen();">OPEN</a></div> <script> function wopen() { var newWindow = window.open('', '_blank'); setTimeout(function () { newWindow.location.href = 'https://stackoverflow.com'; }, 2000); } </script> """ webView.loadHTMLString(htmlString, baseURL: nil) } // 处理window.open创建新窗口的请求 func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { let newWebView = WKWebView(frame: view.bounds, configuration: configuration) newWebView.uiDelegate = self newWebView.navigationDelegate = self view.addSubview(newWebView) return newWebView } // 允许合法的跳转请求 func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { if navigationAction.request.url != nil { decisionHandler(.allow) } else { decisionHandler(.cancel) } } }
关键说明
- 点击链接触发
wopen()后,window.open会调用createWebViewWith方法,我们在这里创建并返回新的 WKWebView,为新窗口提供载体。 - 延迟2秒后的
location.href跳转,会触发新 WebView 的decidePolicyFor代理方法,允许请求后页面就会正常加载目标地址。 - 若不需要多窗口展示,可在跳转后替换原WebView内容或关闭新窗口,根据业务需求调整即可。
内容的提问来源于stack exchange,提问作者SteMa
相关产品推荐
相关产品推荐

