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

我怎样才能可靠地检测使用JavaScript,一个页面加载在一个WKWebView? 我希望能够检测到这些情况:

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

这里有一个关于UIWebView的类似问题。 但是这是相当古老的,我不确定是否仍然适用于WKWebView。

您可以检查WKWebKit用来从JavaScript接收消息的window.webkit.messageHandlers的存在。 如果存在,你在一个WKWebView

结合一个简单的用户代理检查应该做的伎俩:

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

接受的答案不工作,使用WKWebView与UIWebView应用程序进行testing

正如文章所提到的,唯一的HTML5特性差异是IndexedDB的支持。 所以我会select一个更可靠的模式:

  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 } } 

你可能会问:为什么不使用UserAgent? 这是因为Android浏览器使用它作为设置! 所以,我们永远不要相信任何UA。 只有浏览器function和属性检查。

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

9/23/16编辑:我调整了Safari 10的代码,不再允许唯一的IDB检查是可靠的,如@ xmnboy所述。 为了放弃Safari 10,它会检查旧的webkit引擎错误,这个错误只会在Safari 9.2之前被应用。 我使用了一个window.statusbar.visible后备这似乎是一个可靠的指标信号后,iOS 9和10之间的几个比较testing(请检查虽然)

考虑到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 ; } } 

事实certificate,Justin的答案确实是更好的function检测机制,因为它适用于iOS 9和iOS 10。

不知道当我们到了iOS 11时会发生什么::)


资格:如果您使用官方的Cordova WKWebView插件来构build您的webview应用程序,则此testing将起作用,因为该插件会初始化addScriptMessageHandler方法,正如本文的评论中的@hexalys所述。 当WKWebView插件出现时,Cordova正在使用该机制来定义一个新的JS到本地桥接器

在该插件 addScriptMessageHandler中searchaddScriptMessageHandler ,并查看该addScriptMessageHandlerios-wkwebview-exec.js文件的最后一部分实现细节(或者在该文件中searchstringwindow.webkit.messageHandlers )。

看来,由于最新的iOS Chrome使用WKWebView作为渲染引擎,因此Chrome被检测为WKWebView。 ua.indexOf('CriOS')!== -1将有助于在应用程序中区分Chrome和WKWebView。

在iOS中,您可以添加以下代码来build立javascript和objective-c之间的通信:

 WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init]; WKUserContentController *controller = [[WKUserContentController alloc] init]; [controller addScriptMessageHandler:self name:@"javascript_observer"]; configuration.userContentController = controller; 

 webview = [[WKWebView alloc] initWithFrame:... configuration: configuration]; 

在JavaScript中,你可以像这样testing连接:

 if ( window.webkit != undefined ){ //javascript is running in webview }