Erkennen Sie das iPad / iPhone-Webview über Javascript

91

Gibt es eine Möglichkeit, sich über Javascript zu unterscheiden, wenn die Website innerhalb der iPad-Safari oder in einer Anwendung WebView ausgeführt wird?

Rasen
quelle
Ist das nur für iOS-Geräte?
Nicolas S

Antworten:

79

Dies verwendet eine Kombination von window.navigator.userAgentund window.navigator.standalone. Es kann zwischen allen vier Zuständen unterscheiden, die sich auf eine iOS-Webanwendung beziehen: Safari (Browser), Standalone (Vollbild), UIwebview und nicht iOS.

Demo: 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
};
ThinkingStiff
quelle
Chrom hat Safariim userAgent. es verhält sich anders in Bezug auf das Erfordernis eines webcal://Protokolls für .ics-Dateien
neaumusic
@svlada können Sie weitere Informationen bereitstellen? Was war Ihr Gerät und seine iOS-Version?
Sonlexqt
78

Benutzeragenten

Wird in UIWebView ausgeführt

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

Laufen in Safari auf dem iPad

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

Wird in Safari unter Mac OS X ausgeführt

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

Laufen in Chrome unter Mac OS X.

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

Wird in FireFox unter Mac OS X ausgeführt

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

Erkennungscode

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);
neoneye
quelle
Ja wirklich. Ich weiß nicht, warum ich mir beide Useragents überhaupt erst angesehen habe. Vielen Dank für Ihre Antwort :)
sod
4
Funktioniert nicht auf iPhone 5s / iOS 7, da sowohl UIWebViewSafari als auch Safari Safariin ihrem Benutzeragenten
Razor
@ Rasiermesser Du hast recht. Testen gegen Versionim Gegensatz zu Safarifür mich in der neuesten iOS funktioniert.
Unceus
1
@unceus Kannst du bitte genau umreißen, wie du es meinst Version? Ersetzen Sie Safarimit Versionin der var is_uiwebviewLeitung?
Henrik Petterson
@HenrikPetterson In Bezug auf die Zeichenfolgen für Benutzeragenten enthält die UIWebView-Zeichenfolge beim Vergleich der ersten beiden oben genannten Zeichenfolgen für Benutzeragenten (UIWebView und Safari auf dem iPad) die Version, während die Zeichenfolge für das iPad dies nicht tut. Ihr Ziel bei der Änderung des regulären Ausdrucks ist unklar, und es scheint, als würden Sie Hilfe beim Schreiben eines solchen suchen.
Unceus
10

Ich denke, dass Sie nur die verwenden können User-Agent.


AKTUALISIEREN

Mit iPhone Safari durchsuchte Seite

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

Ich werde es gleich mit UIWebView versuchen

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

Der Unterschied ist, dass die Safari sagt Safari/6531.22.7


Lösung

var isSafari = navigator.userAgent.match(/Safari/i) != null;
Nicolas S.
quelle
Ja, aber haben Sie eine Idee, ob es eine bestimmte Zeichenfolge oder etwas gibt, um UIWebView im User-Agent zu erkennen? Bisher konnte ich nichts finden ...
Adam Tal
Ist das nur für iOS-Geräte?
Nicolas S
Nicolas, die Zahlen werden im Moment unterschiedlich sein, da Safari und UIWebView (und "eigenständige" - dh Startbildschirm - Web-Apps) unterschiedliche Engines verwenden. Dies ändert sich in iOS 5.
Ben
Ich meine nicht die Zahlen, ich meine, das Safari/.....selbst fehlt in der UIWebView
Nicolas S
@Nicolas: ganz richtig, sorry ich habe nicht aufgepasst. Ich frage mich, ob jemand bestätigen könnte, ob dies in iOS5 immer noch der Fall ist.
Ben
7

Ja:

// 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);
John Doherty
quelle
11
Dies passt auch zum Safari-Browser, nicht nur zu WebView.
Petr Peller
@ThinkingStuff - Könnten Sie mir helfen, zwischen Mac OS (Desktop-Browser) und iPad Safari-Browser zu unterscheiden - stackoverflow.com/questions/58344491/…
newdeveloper
5

Ich habe alle diese Lösungen ausprobiert, aber in meinem Fall nicht funktioniert.
Ich wollte Telegramm in Webview erkennen. Ich habe festgestellt, dass Safari den Text im Telefonstil in einen Link mit dem Präfix "tel:" ändert. Daher habe ich diesen Code zum Schreiben dieses Codes verwendet. Sie können ihn testen: 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>
Amir Khorsandi
quelle
1
Sie sollten sich nicht auf einen solchen Trick verlassen, da Benutzer oder andere Entwickler die Telefonerkennung deaktivieren können.
19одров Андрей
@ БодровАндрей Ich stimme Ihnen zu, aber das war der einzige Weg, den ich finden konnte. Ich hoffe, Apple bietet in Zukunft einen anderen User-Agent dafür
Amir Khorsandi
Beachten Sie, dass dies unter iOS 13 möglich ist, denn wenn der Desktop-Modus verwendet wird, dann navigator.platform === 'MacIntel'. Dies betrifft insbesondere iPadOS 13 Mobile Safari, da standardmäßig der Desktop-Modus verwendet wird.
Robocat
@robocat du hast recht. Es ist in iOS 13 iPad kaputt und ich stecke gerade ohne Lösung fest. Könnten Sie mir bitte bei verwandten Fragen hier helfen stackoverflow.com/questions/58344491/…
newdeveloper
2

Die Lösung von Neoneye funktioniert nicht mehr (siehe Kommentare) und kann vereinfacht werden. Wenn Sie jedoch nur "Safari" in der UA testen, werden viel mehr Adressen als auf den ios-Handheld-Geräten angesprochen.

Dies ist der Test, den ich benutze:

var is_ios = /(iPhone|iPod|iPad).*AppleWebKit.*Safari/i.test(navigator.userAgent);
Eosphäre
quelle
2

Beachten Sie, dass dieser Ansatz für iOS 10 und ältere Versionen nicht funktioniert.

Für das Frühjahr 2018 hat keine der vorgeschlagenen Methoden für mich funktioniert, daher habe ich einen neuen Ansatz entwickelt (der nicht auf UserAgent basiert):

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

Sie können den Code auch gerne für iPad-Geräte erweitern. Ich denke, das sollte reichen.

Funktionierte gut für Telegramm-, Facebook- und VK-Webviews.

Boris Chumichev
quelle
Für iPhone X wäre es 375/812, ebenfalls neu: 414/896 für iPhone Xs Max / Xr
Oleg Dater
1

Working 15.02.19

Eine andere Lösung zum Erkennen von Webviews unter iOS besteht darin, die Unterstützung / Existenz von zu überprüfen navigator.mediaDevices.

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

In meinem Fall musste ich nicht alle Webansichten abfangen, sondern diejenigen, die keine Kamera- / Mikrofoneingabe unterstützen (Erinnerung: Warnungen werden in Webview nicht ausgelöst, ändern Sie also etwas im Dom für Debug-Zwecke).

vinni
quelle
0

Ich weiß, dass dieser Code über ein Symbol auf dem Startbildschirm überprüft, ob auf ihn zugegriffen wird:

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

Ich bin mir jedoch nicht sicher, wie es in einer UIWebView reagieren würde. Die einzige andere Lösung, die mir in den Sinn kommt, besteht darin, den Benutzeragenten abzurufen oder - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationTypedie Abfragezeichenfolge der Seite, auf die Sie zugreifen, durch etwas zu ersetzen, das die Seite verwendet, um zu identifizieren, dass über eine Webansicht auf sie zugegriffen wird.

Preston
quelle
Danke, ich habe diesen Code verwendet, brauche aber mehr Kontrolle. Es scheint nur den Standalone-Modus zu erkennen und betrachtet den Rest als Safari.
Adam Tal
0

Ich würde vorschlagen, Modernizr zu verwenden und nach indexeddb wie diesem zu suchen . Sie können dies anhand der Konfiguration des Benutzeragenten (Gerät, Betriebssystem, Browser usw.) überprüfen, aber eine reine Funktionserkennung wird empfohlen.

Jiku
quelle
Klingt nach einem Plan, aber auf welche Funktionen würden Sie testen? indexeddb ist Teil von dh, Chrome, Firefox usw.
SSED
0

Als ich dies das letzte Mal brauchte (NUR für WebView-Zwecke), habe ich diese Prüfung verwendet:

function isIOS() {
     return !/safari/.test( window.navigator.userAgent.toLowerCase()) || navigator.platform === 'iOS' || navigator.platform === 'iPhone';
}
CatalinBerta
quelle
Dies ist im iOS13-Desktop-Modus (Plattform nicht mehr auf iPad oder iPhone eingestellt) und auf dem iPod touch (Plattform kann "iPod" oder "iPod touch" sein) fehlerhaft.
Robocat
0

Ich habe eine einfache Lösung gefunden, um iPhone oder iPad zu erkennen. Das funktioniert bei mir gut.

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
    }
Vijay Dhanvai
quelle
0

Versuchen Sie es mit 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)
Mahmoud D. Alghraibeh
quelle
-2

Ich glaube nicht, dass Sie in clientseitigem Javascript etwas Spezielles verwenden können, aber wenn Sie die Kontrolle darüber haben, was das ursprüngliche UIWebView tun kann, sollten Sie in Betracht ziehen, mit der von ihm generierten Benutzeragentenzeichenfolge zu spielen und dies in Ihrem zu testen clientseitiges Javascript statt? Ein bisschen wie ein Hack, den ich kenne, aber hey ... Diese Frage kann einige Hinweise zum Optimieren des Benutzeragenten geben:

Benutzeragent in UIWebView ändern (iPhone SDK)

Ben
quelle
Danke, Ben. Leider habe ich keine Kontrolle über den UIWebView-Benutzeragenten der App.
Adam Tal
-7

@ Sod, Nun, ich habe keine Antwort, aber ich bin nicht überzeugt, warum Sie überprüfen möchten, da die Browser-Engine, ob ihre Safari (Browser) oder Anwendung nur mit ihrem Webkit identisch ist, Ja, Anwendung kann die Browser-Engine-Funktionen wie konfigurieren , ob die Anwendung JS oder Display Image usw. ausführen möchte…

Ich glaube, Sie müssen auf bestimmte Eigenschaften prüfen, ob Flash vom Browser unterstützt wird oder ob der Browser ein Bild anzeigt oder nicht, oder ob Sie möglicherweise die Bildschirmgröße überprüfen möchten.

Amitg2k12
quelle
Sie könnten dies in den Kommentaren diskutieren. Wie auch immer, es gibt viele Fälle, um wevbview zu überprüfen
Yozi