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

iOS WKWebView的addUserScript首次作用于about:blank页面时不生效

iOS WKWebView的addUserScript首次作用于about:blank页面时不生效

我之前做WKWebView相关开发的时候,正好碰到过和你一模一样的问题!给普通网站用addUserScript加脚本都好好的,唯独第一次加载about:blank页面时,脚本死活不生效,当时折腾了好一阵才摸清楚门道。

其实这是WKWebView的一个小“坑”——about:blank属于本地空白页面,它的加载流程和普通HTTP/HTTPS页面完全不一样:没有网络请求、页面资源都是本地生成的,首次加载时WebView的内部初始化状态还没完全就绪,导致你提前加到WKWebViewConfiguration里的userScript没办法被正确注入到这个空白页面中。

给你两个亲测有效的解决办法:

  • 方法一:直接用evaluateJavaScript注入脚本(最可靠)
    放弃在WebView初始化时通过addUserScript配置脚本,等about:blank页面加载完成后,直接调用evaluateJavaScript执行你的脚本内容。这样能确保页面已经完全就绪,脚本肯定能生效。
    具体代码示例:

    import UIKit
    import WebKit
    
    class ViewController: UIViewController, WKNavigationDelegate {
        var webView: WKWebView!
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            webView = WKWebView(frame: view.bounds)
            webView.navigationDelegate = self
            view.addSubview(webView)
            
            // 加载about:blank页面
            webView.load(URLRequest(url: URL(string: "about:blank")!))
        }
    
        // 监听页面加载完成事件,注入脚本
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            guard webView.url?.absoluteString == "about:blank" else { return }
            
            // 替换成你实际需要执行的脚本内容
            let targetScript = """
                document.body.style.backgroundColor = '#f0f0f0';
                console.log('脚本成功注入about:blank页面啦');
            """
            
            webView.evaluateJavaScript(targetScript) { result, error in
                if let error = error {
                    print("脚本执行出错:\(error.localizedDescription)")
                }
            }
        }
    }
    
  • 方法二:调整脚本注入时机 + 重新触发加载(备选方案)
    如果你坚持要用addUserScript的方式,可以试试把脚本的注入时机改成.atDocumentEnd,然后在页面首次加载完成后重新加载一次,触发脚本注入。不过这种方法不如第一种可靠,偶尔还是会有玄学问题:

    import UIKit
    import WebKit
    
    class ViewController: UIViewController, WKNavigationDelegate {
        var webView: WKWebView!
        private var hasReloaded = false
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            let config = WKWebViewConfiguration()
            // 把注入时机改成atDocumentEnd
            let customScript = WKUserScript(
                source: "document.body.style.backgroundColor = '#f0f0f0';",
                injectionTime: .atDocumentEnd,
                forMainFrameOnly: true
            )
            config.userContentController.addUserScript(customScript)
            
            webView = WKWebView(frame: view.bounds, configuration: config)
            webView.navigationDelegate = self
            view.addSubview(webView)
            
            webView.load(URLRequest(url: URL(string: "about:blank")!))
        }
    
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            // 首次加载完成后重新加载,触发脚本注入
            if webView.url?.absoluteString == "about:blank" && !hasReloaded {
                hasReloaded = true
                webView.reload()
            }
        }
    }
    

个人更推荐第一种方法,不仅逻辑清晰,还完全避开了WKWebView对about:blank的特殊处理逻辑,不会有奇怪的不生效问题。

备注:内容来源于stack exchange,提问作者sudoExclamationExclamation

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 16:34:43