在 Swift WKWebView 中捕获 window.postMessage

MFD*_*000 7 javascript native ios swift wkwebview

我正在开发一个WKWebView用于加载电子商务网站的 swift ios 应用程序。
当用户在这里购买产品时,结账页面允许用户使用加密货币支付。

当用户点击“在钱包中打开”时,网站会发出一个 window.postMessage(paymentData) 支付数据是一个 js 对象,其中包含一个比特币 URL。

我正在使用WKUserScriptwithWKWebConfiguration注入一个脚本,该脚本侦听窗口消息,然后将数据发送到我的webkit.messageHandler.

let source = """
    window.addEventListener('message', function(e) { window.webkit.messageHandlers.iosListener.postMessage(JSON.stringify(e.data)) } )
    """
Run Code Online (Sandbox Code Playgroud)

不幸的是,这段代码永远不会触发。

当我使用 chrome 或 safari devtools 注入相同的 javascript 时,它工作得很好。

我已经搜索了堆栈溢出以查看window.postMessagein是否存在特殊条件,WKWebView但到目前为止还没有运气。

是否可以捕获window.postMessage()事件并将事件数据通过管道传输回我的 ios 应用程序?

提前致谢!!!!这是我现有的代码。

  let webConfiguration = WKWebViewConfiguration()
    let source = """
    window.addEventListener('message', function(e) { window.webkit.messageHandlers.iosListener.postMessage(JSON.stringify(e.data)) } )
    """
    let script = WKUserScript(source: source, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
    userContentController.addUserScript(script)

    userContentController.add(self, name: "iosListener")
    webConfiguration.userContentController = userContentController
    webView = WKWebView(frame: .zero, configuration: webConfiguration)
    webView.uiDelegate = self
    webView.navigationDelegate = self
    webView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(webView)
Run Code Online (Sandbox Code Playgroud)
 func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    print("message body: \(message.body)")
    print("message frameInfo: \(message.frameInfo)")
  }
Run Code Online (Sandbox Code Playgroud)

Gus*_*cht 6

对的,这是可能的。您还需要设置javascriptEnabled = true

self.webView.configuration.preferences.javaScriptEnabled = true
Run Code Online (Sandbox Code Playgroud)

您还可以像这样配置侦听器:

self.webView.configuration.userContentController.add(self, name: "iosListener")
Run Code Online (Sandbox Code Playgroud)

并确保您在应用这两个命令之前

self.webView.load(/*some request*/)
Run Code Online (Sandbox Code Playgroud)

您可以在页面didFinish加载后进行简单的测试:

self.webView.evaluateJavaScript("window.webkit.messageHandlers.iosListener.postMessage('test');", completionHandler: { (result, err) in
    if (err != nil) {
        // show error feedback to user.
    }
})
Run Code Online (Sandbox Code Playgroud)

另一个建议是;在与 javascript 代码交互时始终在命令末尾添加,webView因为有些人可以依赖标准 javascript。

let source = """
    window.addEventListener('message', function(e) {
        window.webkit.messageHandlers.iosListener.postMessage(JSON.stringify(e.data));
    });
    """
Run Code Online (Sandbox Code Playgroud)

注意:我还建议将webView用作类变量而不是方法变量,您可能正在创建它viewDidLoad(),我建议您将变量移动到您的类中。

var webView: WKWebView!