在 Swift WKWebView 中捕获 window.postMessage

Posted

技术标签:

【中文标题】在 Swift WKWebView 中捕获 window.postMessage【英文标题】:Capture window.postMessage in Swift WKWebView 【发布时间】:2019-06-20 19:03:47 【问题描述】:

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

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

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

let source = """
    window.addEventListener('message', function(e)  window.webkit.messageHandlers.iosListener.postMessage(JSON.stringify(e.data))  )
    """

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

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

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

是否可以捕获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)
 func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) 
    print("message body: \(message.body)")
    print("message frameInfo: \(message.frameInfo)")
  

【问题讨论】:

你解决了吗?考虑支持/接受/与答案互动,为网站生成有价值的知识。提出一个问题然后再也不回答它不是一个好习惯。 嗨@GustavoVollbrecht。我正在度假,希望我能得到更多的答案。感谢您的贡献,但遗憾的是我们仍然无法捕捉到 window.postMessage 事件。奇怪的是我们可以捕获任何其他事件,例如 onClick。我们无法捕获具体是window.postMessage(JSON.stringify(data), '*');。如果您有兴趣,我可以与您分享该网站的网址。再次感谢。我赞成你的回答。 @MFD3000,你解决了吗?我也遇到了这个。更改为 injectionTime: .atDocumentStart 后我得到了它 @JannoTeelem:如果我使用atDocumentStart,我的代码现在也可以工作。如果这个答案适用于 OP,那将会很有趣。 @MFD3000 我也遇到了类似的问题,你解决了吗? 【参考方案1】:

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

self.webView.configuration.preferences.javaScriptEnabled = true

你也可以像这样配置监听器:

self.webView.configuration.userContentController.add(self, name: "iosListener")

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

self.webView.load(/*some request*/)

你可以在页面didFinish加载后做一个简单的测试:

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

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

let source = """
    window.addEventListener('message', function(e) 
        window.webkit.messageHandlers.iosListener.postMessage(JSON.stringify(e.data));
    );
    """

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

var webView: WKWebView!

【讨论】:

@SmarterSusheel 在他的下一行,WKUserScript init @GustavoVollbrecht 我需要在 iOS 应用程序中监听第三方的付款响应,并且我正在使用上面的消息事件监听器,并且 userContentController 方法在收到第三方的响应后没有命中,而其他监听器正在为例如,焦点,点击正在点击 userContentController。请指教 @subha 请发布您自己的问题,并提供很多详细信息。

以上是关于在 Swift WKWebView 中捕获 window.postMessage的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Xamarin IOS 中捕获 WkWebView 的屏幕

WKWebView:表单未在 WKWebView (Swift) 中提交

WKWebview捕获AJAX

Swift:使用 URLSession 的“表达式类型不明确,没有更多上下文”

在 Swift 中使用 WKWebView 进行身份验证

在 Swift 中使用 JS 隐藏 WKWebView 集合元素