通过 javascript 检测 ipad/iphone webview

Posted

技术标签:

【中文标题】通过 javascript 检测 ipad/iphone webview【英文标题】:detect ipad/iphone webview via javascript 【发布时间】:2011-05-26 12:04:13 【问题描述】:

如果网站运行在 iPad 的 Safari 内或应用程序 WebView 内,有没有办法使用 javascript 检测?

【问题讨论】:

这仅适用于 ios 设备吗? 【参考方案1】:

我已经尝试了所有这些解决方案,但在我的情况下都不起作用, 我打算检测Telegram 中的Webview。我认为它使用SFSafariViewController。 我注意到 Safari 应用程序将所有电话样式文本更改为带有“tel:”前缀的链接,但 webview 没有。 所以,我用了那个。 在这里测试:jsfiddle

<!DOCTYPE html>
<html>
<head></head>
<body>
<ul id="phone" style="opacity:0">
    <li>111-111-1111</li>
</ul>
</body>
</html>

<script>

    var html = document.getElementById("phone").innerHTML;

    if (navigator.platform.substr(0,2) === 'iP') 

        if (html.indexOf('tel:') == -1)
            alert('not safari browser');
        else
            alert('safari browser');
    
    else
        alert('not iOS');
</script>

【讨论】:

您不应该依赖这种技巧,因为用户或任何其他开发人员可以禁用电话检测。 @БодровАндрей 我同意你的看法,但这是我能找到的唯一方法,我希望苹果将来为此提供不同的用户代理 注意这在 iOS 13 上是 borken,因为如果使用桌面模式,那么 navigator.platform === 'MacIntel'。这尤其会影响 iPadOS 13 Mobile Safari,因为它默认使用桌面模式。 @robocat 你是对的。它在 iOS 13 iPad 中坏了,我现在没有解决方案。你能帮我解决相关问题吗***.com/questions/58344491/…【参考方案2】:

尝试使用 IOS 13

      function mobileDetect() 


    var agent = window.navigator.userAgent;
    var d = document;
    var e = d.documentElement;
    var g = d.getElementsByTagName('body')[0];
    var deviceWidth = window.innerWidth || e.clientWidth || g.clientWidth;

    // Chrome
    IsChromeApp = window.chrome && chrome.app && chrome.app.runtime;

    // iPhone
    IsIPhone = agent.match(/iPhone/i) != null;

    // iPad up to IOS12
    IsIPad = (agent.match(/iPad/i) != null) || ((agent.match(/iPhone/i) != null) && (deviceWidth > 750)); // iPadPro when run with no launch screen can have error in userAgent reporting as an iPhone rather than an iPad. iPadPro width portrait 768, iPhone6 plus 414x736 but would probably always report 414 on app startup

    if (IsIPad) IsIPhone = false;

    // iPad from IOS13
    var macApp = agent.match(/Macintosh/i) != null;
    if (macApp) 
        // need to distinguish between Macbook and iPad
        var canvas = document.createElement("canvas");
        if (canvas != null) 
            var context = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
            if (context) 
                var info = context.getExtension("WEBGL_debug_renderer_info");
                if (info) 
                    var renderer = context.getParameter(info.UNMASKED_RENDERER_WEBGL);
                    if (renderer.indexOf("Apple") != -1) IsIPad = true;
                
                ;
            
            ;
        
        ;
    
    ;

    // IOS
    IsIOSApp = IsIPad || IsIPhone;

    // android
    IsAndroid = agent.match(/Android/i) != null;
    IsAndroidPhone = IsAndroid && deviceWidth <= 960;
    IsAndroidTablet = IsAndroid && !IsAndroidPhone;



    message = ""


    if (IsIPhone) 

        message = "Device is IsIPhone"


    
    else if (IsIPad) 

        message = "Device is ipad"

     else if (IsAndroidTablet || IsAndroidPhone || IsAndroid) 

        message = "Device is Android"


     else 

        message = "Device is Mac ||  Windows Desktop"

    


    return 

        message: message,

        isTrue: IsIOSApp || IsAndroid || IsAndroidTablet || IsAndroidPhone

    





const checkMobile = mobileDetect()

alert(checkMobile.message + "  =====>  " + checkMobile.isTrue)

【讨论】:

【参考方案3】:

Working 15.02.19

在 iOS 上检测 webview 的另一种解决方案是检查 navigator.mediaDevices 的支持/存在。

if (navigator.mediaDevices) 
    alert('has mediaDevices');
 else 
    alert('has no mediaDevices');

在我的情况下,我不需要捕获所有 webview,但那些不支持摄像头/麦克风输入的 webview(提醒:警报不会在 Webview 中触发,因此请确保在 dom 中更改某些内容以进行调试)

【讨论】:

Safari 和 Telegram 都有 mediaDevices @Chris 你说 Telegram 是什么意思?单击消息中的链接时打开的内置浏览器?它不是 webview,它是一个应用内浏览器,类似于常规的 Safari,但与真正的 webview 非常不同。 似乎这段代码是当今最可靠的。但请记住,navigator.mediaDevices 在 HTTP 页面上是不存在的,因此您不能在 HTTP 页面上使用此方法。【参考方案4】:

请注意,此方法不适用于 iOS 10 及更早版本。

对于 2018 年春季,没有一个建议的方法对我有用,所以我想出了一种新方法(不是基于 userAgent):

const hasValidDocumentElementRatio =
  [ 320 / 454 // 5, SE
  , 375 / 553 // 6, 7, 8
  , 414 / 622 // 6, 7, 8 Plus
  , 375 / 812 // X
  , 414 / 896 // Xs, Xr
  ].some(ratio =>
    ratio === document.documentElement.clientWidth / 
      document.documentElement.clientHeight
  )

const hasSafariInUA = /Safari/.test(navigator.userAgent)

const isiOSSafari = hasSafariInUA && hasValidDocumentElementRatio  // <- this one is set to false for webviews

https://gist.github.com/BorisChumichev/7c0ea033daf33da73306a396ffa174d1

欢迎您也为 iPad 设备扩展代码,我认为它应该可以解决问题。

适用于 Telegram、Facebook、VK 网页浏览。

【讨论】:

iPhone X 为 375 / 812,也是新的:iPhone Xs Max/Xr 为 414 / 896 对于 iPhone 12,横向模式为 390 / 664 & 750 / 307【参考方案5】:

我找到了一种检测 iPhone 或 iPad 的简单解决方案。这对我来说很好。

var is_iPad = navigator.userAgent.match(/iPad/i) != null;
var is_iPhone = navigator.userAgent.match(/iPhone/i) != null;
    if(is_iPad || is_iPhone == true)
        //perform your action
    

【讨论】:

【参考方案6】:

上次我需要这个(仅用于 WebView 目的),我使用了这个检查:

function isIOS() 
     return !/safari/.test( window.navigator.userAgent.toLowerCase()) || navigator.platform === 'iOS' || navigator.platform === 'iPhone';

【讨论】:

这在 iOS13 桌面模式(平台不再设置为 iPad 或 iPhone)和 iPod touch(平台可以是“iPod”或“iPod touch”)上被破坏。【参考方案7】:

用户代理

在 UIWebView 中运行

Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/98176

在 iPad 上的 Safari 中运行

Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B176 Safari/7534.48.3

在 Mac OS X 上的 Safari 中运行

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.5 Safari/534.55.3

在 Mac OS X 上的 Chrome 中运行

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.151 Safari/535.19

在 Mac OS X 上的 FireFox 中运行

Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0

检测码

var is_uiwebview = /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent);
var is_safari_or_uiwebview = /(iPhone|iPod|iPad).*AppleWebKit/i.test(navigator.userAgent);

【讨论】:

真的。我不知道为什么我首先自己查看了两个用户代理。谢谢你的回答:) 不适用于 iPhone 5s/iOS 7,因为 UIWebView 和 Safari 在其用户代理中都有 Safari @Razor 你是对的。在最新的 iOS 中,针对 Version 而不是 Safari 的测试对我有用。 @unceus 你能具体说明一下Version 的意思吗?您是否将var is_uiwebview 行中的Version 替换为Safari @HenrikPetterson 关于用户代理字符串,比较上面的前两个用户代理字符串(UIWebView 和 iPad 上的 Safari),UIWebView 字符串包含“版本”,而 ipad 则没有。您修改正则表达式的目标尚不清楚,听起来您可能正在寻求帮助。【参考方案8】:

建议使用Modernizr,并检查像this 这样的indexeddb。您可以使用用户代理配置(设备、操作系统、浏览器等)进行交叉检查,但似乎更推荐使用纯特征检测。

【讨论】:

听起来像是一个计划,但您会测试哪些功能? indexeddb 是 ie、chrome、firefox 等的一部分【参考方案9】:

Neoneye 的解决方案不再起作用(请参阅 cmets)并且可以简化。 另一方面,在 UA 中仅测试“Safari”的地址比 ios 手持设备要多得多。

这是我正在使用的测试:

var is_ios = /(iPhone|iPod|iPad).*AppleWebKit.*Safari/i.test(navigator.userAgent);

【讨论】:

【参考方案10】:

是的:

// is this an IPad ?
var isiPad = (navigator.userAgent.match(/iPad/i) != null);

// is this an iPhone ?
var isiPhone = (navigator.userAgent.match(/iPhone/i) != null);

// is this an iPod ?
var isiPod = (navigator.userAgent.match(/iPod/i) != null);

【讨论】:

这也将匹配 Safari 浏览器,而不仅仅是 WebView。 @ThinkingStuff - 你能帮我区分 Mac OS(桌面浏览器)和 iPad Safari 浏览器 - ***.com/questions/58344491/…【参考方案11】:

这使用了window.navigator.userAgentwindow.navigator.standalone 的组合。它可以区分与 iOS 网络应用相关的所有四种状态:safari(浏览器)、独立(全屏)、uiwebview 和非 iOS。

演示:http://jsfiddle.net/ThinkingStiff/6qrbn/

var standalone = window.navigator.standalone,
    userAgent = window.navigator.userAgent.toLowerCase(),
    safari = /safari/.test( userAgent ),
    ios = /iphone|ipod|ipad/.test( userAgent );

if( ios ) 
    if ( !standalone && safari ) 
        //browser
     else if ( standalone && !safari ) 
        //standalone
     else if ( !standalone && !safari ) 
        //uiwebview
    ;
 else 
    //not iOS
;

【讨论】:

chrome 在 userAgent 中有 Safari。对于 .ics 文件要求 webcal:// 协议,它的行为有所不同 @svlada 你能提供更多信息吗?您的设备及其 iOS 版本是什么? Safari 和 Telegram 在用户代理中都包含“safari”,所以这不起作用【参考方案12】:

我认为你可以使用User-Agent


更新

使用 iPhone Safari 浏览的页面

Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7

我稍后会尝试使用 UIWebView

Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Mobile/8B117

不同之处在于 Safari 显示Safari/6531.22.7


解决方案

var isSafari = navigator.userAgent.match(/Safari/i) != null;

【讨论】:

是的,但是您知道在 User-Agent 中是否有特定的字符串或其他东西可以检测 UIWebView 吗?到目前为止,我找不到任何东西...... 这仅适用于 iOS 设备吗? Nicolas 目前的数字会有所不同,因为 Safari 和 UIWebView(以及“独立”——即主屏幕——网络应用程序)使用不同的引擎。这在 iOS 5 中发生了变化。 我不是指数字,我的意思是 UIWebView 中缺少 Safari/..... 本身 @Nicolas:非常正确,抱歉我没注意。我想知道是否有人可以确认iOS5中是否仍然如此?【参考方案13】:

我不认为你可以在客户端 Javascript 中使用任何特定的东西,但如果你可以控制原始 UIWebView 可以做什么,你可能需要考虑使用它生成的用户代理字符串,并测试而是在您的客户端Javascript中?我知道有点 hack,但是,嘿……这个问题可能会为调整用户代理提供一些指导:

Change User Agent in UIWebView (iPhone SDK)

【讨论】:

谢谢,本。不幸的是,我无法控制应用的 UIWebView 用户代理。【参考方案14】:

我知道这段代码会检查是否从添加到主屏幕的图标访问它:

if (window.navigator.standalone == true) 
//not in safari

但我不确定它在 UIWebView 中会如何反应。我能想到的唯一其他解决方案是获取用户代理或使用- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 并将您正在访问的页面的查询字符串替换为页面用来识别它正在从网络视图访问的内容。

【讨论】:

谢谢,我正在使用该代码,但需要更多控制。它似乎只检测独立模式,并认为其余的是 Safari。【参考方案15】:

@草皮, 好吧,我没有答案,但我不相信你为什么要检查,因为浏览器引擎是否它的 safari(浏览器)或应用程序将与它的 Webkit 相同, 是的,应用程序可以配置浏览器引擎功能,例如,应用程序是要运行 JS 还是显示图像等……

我相信,您必须检查浏览器是否支持Flash或浏览器是否显示图像的某些属性,或者您可能想检查屏幕大小,

【讨论】:

你可以在 cmets 中讨论这个问题。反正有很多情况要检查wevbview

以上是关于通过 javascript 检测 ipad/iphone webview的主要内容,如果未能解决你的问题,请参考以下文章

通过 Javascript 检测 Windows 11

通过 Javascript / jQuery 检测 Android 手机

通过 JavaScript 检测用户设备是不是使用移动操作系统

javascript [通过移动设备检测浏览]

如何通过分析 JavaScript & HTML 来检测 HTTP 请求?

通过浏览器检测用户不活动 - 纯粹通过 javascript [重复]