检测是否在JavaScript中的WKWebView内加载了页面

and*_*111 19 javascript mobile-safari uiwebview ios wkwebview

如何使用javascript可靠地检测到在WKWebView中加载页面?我希望能够检测到这些情况:

  • iOS和WKWebView
  • iOS和Safari
  • 不是iOS

有一个关于UIWebView的一个类似的问题在这里.但它已经很老了,我不确定它是否仍适用于WKWebView.

hex*_*lys 30

使用WKWebView与UIWebView应用程序测试后,接受的答案无效

正如文章所提到的,唯一的HTML5功能差异是IndexedDB支持.所以我会寻求更可靠的模式:

    if (navigator.platform.substr(0,2) === 'iP'){
      //iOS (iPhone, iPod or iPad)
      var lte9 = /constructor/i.test(window.HTMLElement);
      var nav = window.navigator, ua = nav.userAgent, idb = !!window.indexedDB;
      if (ua.indexOf('Safari') !== -1 && ua.indexOf('Version') !== -1 && !nav.standalone){      
        //Safari (WKWebView/Nitro since 6+)
      } else if ((!idb && lte9) || !window.statusbar.visible) {
        //UIWebView
      } else if ((window.webkit && window.webkit.messageHandlers) || !lte9 || idb){
        //WKWebView
      }
    }
Run Code Online (Sandbox Code Playgroud)

您可能会问:为什么不使用UserAgent?这是因为Android浏览器将其用作设置!所以,我们永远不要相信任何UA.仅浏览器功能和属性检查.

另外我注意到QuickTime插件总是作为旧的Safari和UIWebView中的其他浏览器的一部分加载.但是WKWebView中不再存在该插件.因此,您可以使用QuickTime插件存在作为额外检查.

9/23/16编辑:我调整了Safari 10的代码,不再允许唯一的idb检查是可靠的,如@xmnboy所述.要丢弃Safari 10,它会检查旧的webkit引擎错误,该错误仅适用于Safari 9.2; 我window.statusbar.visible在iOS 9和10之间进行了一些比较测试之后使用了一个可靠的指示信号.(请检查)

  • 不幸的是,这种方法不再起作用。它在iOS 9设备上运行良好,但是在iOS 10设备上,即使您位于UIWebView中,window.indexedDB的检查也将变为正确。 (2认同)

xmn*_*boy 5

鉴于Apple在iOS 10中对UIWebView的行为进行了更改,这是一个新答案,该答案结合了@ Justin-Michael的原始响应和@hexalys的后续收藏。

var isWKWebView = false ;
if( navigator.platform.substr(0,2) === 'iP' ) {    // iOS detected
    if( window.webkit && window.webkit.messageHandlers ) {
        isWKWebView = true ;
    }
}
Run Code Online (Sandbox Code Playgroud)

事实证明,贾斯汀的答案确实是更好的功能检测机制,因为它适用于iOS 9和iOS 10。

不知道当我们进入iOS 11时会发生什么。:-)


资格:如果您使用的是官方的Cordova WKWebView插件来构建您的Webview应用程序,则此测试将起作用,因为该插件确实初始化了该addScriptMessageHandler方法,如@hexalys在本文评论中所述。当存在WKWebView插件时,Cordova正在使用该机制来定义到本机桥的新JS

搜索addScriptMessageHandler该插件回购,看到的最后ios-wkwebview-exec.js文件在回购的一些实施细则(或搜索字符串window.webkit.messageHandlers在该文件)。

  • 同样,默认情况下,webkit 并不总是所有 iOS 视图上的已定义对象。所以在JS端不可靠。正如[这个答案](http://stackoverflow.com/a/32785085/1647538)所述。“window.webkit 命名空间仅出现在带有脚本消息处理程序的 webview 中。请确保您已调用 WKUserContentController 的 addScriptMessageHandler 方法。” 例如,测试应用程序肯定没有设置它。 (2认同)

Jus*_*ael -2

更新:这不再有效,请参阅上面评价较高的答案!

您可以检查window.webkit.messageHandlersWKWebKit 是否存在用于接收来自 JavaScript 的消息。如果它存在,那么您就在一个WKWebView.

与简单的用户代理检查相结合应该可以解决问题:

var iOS = (navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? true : false);
var isWKWebView = false;
if (window.webkit && window.webkit.messageHandlers) {
    isWKWebView = true;
}
Run Code Online (Sandbox Code Playgroud)