détecter la vue web ipad / iphone via javascript


91

Existe-t-il un moyen de différer via javascript si le site Web fonctionne à l'intérieur de l'ipad safari ou à l'intérieur d'une application WebView?


Est-ce uniquement pour les appareils iOS?
Nicolas S

Réponses:


79

Cela utilise une combinaison de window.navigator.userAgentet window.navigator.standalone. Il peut distinguer les quatre états relatifs à une application Web iOS: safari (navigateur), autonome (plein écran), uiwebview et non iOS.

Démo: 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 a Safaridans le userAgent. il se comporte différemment en ce qui concerne le webcal://protocole requis pour les fichiers .ics
neaumusic

@svlada pouvez-vous fournir plus d'informations? Quel était votre appareil et sa version iOS?
sonlexqt

78

Agents utilisateurs

Exécution dans UIWebView

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

Exécution dans Safari sur 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

Exécution dans Safari sur Mac OS X

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

Exécution dans Chrome sur 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

Exécution dans FireFox sur Mac OS X

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

Code de détection

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);

Vraiment. Je ne sais pas pourquoi j'ai regardé les deux useragents moi-même en premier lieu. Merci pour votre réponse :)
gazon

4
Ne fonctionne pas sur iPhone 5s / iOS 7, car les deux UIWebViewet Safari ont Safaridans leur agent utilisateur
Razor

@Razor Vous avez raison. Tester Versionpar opposition à a Safarifonctionné pour moi dans le dernier iOS.
unceus

1
@unceus Pouvez-vous décrire exactement ce que vous entendez par là Version? Remplacez-vous Safaripar Versiondans la var is_uiwebviewligne?
Henrik Petterson

@HenrikPetterson En ce qui concerne les chaînes d'agent utilisateur, en comparant les deux premières chaînes d'agent utilisateur ci-dessus (UIWebView et Safari sur iPad), la chaîne UIWebView contient «version», contrairement à celle d'ipad. Votre objectif avec la modification de l'expression régulière n'est pas clair, et il semble que vous cherchiez peut-être de l'aide pour en écrire une.
unceus

10

Je pense que vous pouvez simplement utiliser le User-Agent.


METTRE À JOUR

Page parcourue avec 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

J'essaierai dans une seconde avec 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

La différence est que le Safari dit Safari/6531.22.7


Solution

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

Ouais, mais avez-vous une idée s'il y a une chaîne spécifique ou quelque chose pour détecter UIWebView dans User-Agent? Jusqu'à présent, je n'ai rien trouvé ...
Adam Tal

Est-ce uniquement pour les appareils iOS?
Nicolas S

Nicolas les chiffres seront différents pour le moment car Safari et UIWebView (et les applications web «autonomes» - écran d'accueil - utilisent des moteurs différents. Cela change dans iOS 5.
Ben

Je ne parle pas des chiffres, je veux dire que le Safari/.....lui-même manque dans l'UIWebView
Nicolas S

@Nicolas: tout à fait raison, désolé je n'ai pas fait attention. Je me demande si quelqu'un pourrait confirmer si c'est toujours le cas dans iOS5?
Ben

7

Ouais:

// 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);

11
Cela correspondra également au navigateur Safari et non seulement à WebView.
Petr Peller

@ThinkingStuff - Pourriez-vous m'aider à faire la différence entre Mac OS (navigateur de bureau) et le navigateur Safari pour iPad - stackoverflow.com/questions/58344491/…
newdeveloper

5

J'ai essayé toutes ces solutions mais cela n'a pas fonctionné dans mon cas,
j'allais détecter Telegram dans Webview. J'ai remarqué que Safari change le texte du style du téléphone en un lien avec le préfixe "tel:", donc j'ai utilisé ceci pour écrire ce code, vous pouvez le tester: 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>

1
Vous ne devez pas vous fier à une telle astuce car l'utilisateur ou tout autre développeur peut désactiver la détection téléphonique.
Бодров Андрей

@ БодровАндрей Je suis d'accord avec vous, mais c'était le seul moyen que je pouvais trouver, j'espère que Apple fournira différents User-Agent pour cela à l'avenir
Amir Khorsandi

Attention, c'est borken sur iOS 13, car si le mode bureau est utilisé, alors navigator.platform === 'MacIntel'. Cela affecte particulièrement iPadOS 13 Mobile Safari car il utilise le mode bureau par défaut.
robocat

@robocat vous avez raison. son cassé dans iOS 13 iPad et je suis actuellement bloqué sans solution. Pourriez-vous s'il vous plaît m'aider avec une question connexe ici stackoverflow.com/questions/58344491/…
newdeveloper

2

La solution de Neoneye ne fonctionne plus (voir commentaires) et peut être simplifiée. D'un autre côté, tester uniquement "Safari" dans l'UA adresse beaucoup plus que les appareils portables ios.

Voici le test que j'utilise:

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

2

Notez que cette approche ne fonctionne pas pour iOS 10 et les versions antérieures.

Pour le printemps 2018, aucune des méthodes proposées n'a fonctionné pour moi, j'ai donc proposé une nouvelle approche (qui n'est pas basée sur 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

Vous êtes également invité à étendre le code pour les appareils iPad, je pense que cela devrait faire l'affaire.

A bien fonctionné pour Telegram, Facebook, VK webviews.


Pour iPhone X, ce serait 375/812, également nouveau: 414/896 pour iPhone Xs Max / Xr
Oleg Dater

1

Working 15.02.19

Une autre solution pour détecter les vues Web sur iOS consiste à vérifier la prise en charge / l'existence de navigator.mediaDevices.

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

Dans mon cas, je n'ai pas eu besoin de capturer toutes les vues Web, mais celles qui ne prennent pas en charge l'entrée caméra / microphone (rappel: les alertes ne se déclenchent pas dans Webview, alors assurez-vous de modifier quelque chose dans le dom à des fins de débogage)


0

Je sais que ce code vérifiera s'il est accessible à partir d'une icône ajoutée à l'écran d'accueil:

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

mais je ne sais pas comment il réagirait dans un UIWebView. La seule autre solution à laquelle je pourrais penser est d'obtenir l'agent utilisateur ou d'utiliser - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationTypeet de remplacer la chaîne de requête de la page à laquelle vous accédez par quelque chose que la page utilise pour identifier qu'elle est accessible à partir d'une vue Web.


Merci, j'utilisais ce code, mais j'ai besoin de plus de contrôle. Il semble ne détecter que le mode autonome et considère que le reste est Safari.
Adam Tal

0

Je suggère d'utiliser Modernizr et de vérifier indexeddb comme ceci . Vous pouvez contre-vérifier cela avec la configuration de l'agent utilisateur (périphérique, système d'exploitation, navigateur, etc.), mais la détection des fonctionnalités pures semble plus recommandée.


Cela ressemble à un plan, mais quelles fonctionnalités testeriez-vous? indexeddb fait partie de ie, chrome, firefox etc
SSED

0

La dernière fois que j'en ai eu besoin (JUSTE à des fins WebView), j'ai utilisé cette vérification:

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

Ceci est cassé en mode bureau iOS13 (la plate-forme n'est plus réglée sur iPad ou iPhone) et sur l'iPod touch (la plate-forme peut être «iPod» ou «iPod touch»).
robocat

0

J'ai trouvé une solution simple pour détecter un iPhone ou un iPad. Cela fonctionne bien pour moi.

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
    }

0

Essayez avec 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)

-2

Je ne pense pas que vous puissiez utiliser quoi que ce soit de spécifique dans Javascript côté client, mais si vous avez le contrôle sur ce que l'UIWebView d'origine peut faire, vous voudrez peut-être envisager de jouer avec la chaîne d'agent utilisateur qu'il génère et de tester cela dans votre Javascript côté client à la place? Un petit hack je sais, mais bon… Cette question peut donner quelques conseils pour peaufiner l'agent utilisateur:

Changer l'agent utilisateur dans UIWebView (iPhone SDK)


Merci Ben. Malheureusement, je n'ai pas de contrôle sur l'agent utilisateur UIWebView de l'application.
Adam Tal

-7

@ Sod, Eh bien, je n'ai pas de réponse, mais je ne suis pas convaincu pourquoi vous voulez vérifier, Depuis, le moteur de navigateur si son safari (navigateur) ou son application sera le même que son Webkit, Oui, l'application peut configurer les capacités du moteur du navigateur comme , si l'application souhaite exécuter JS ou afficher l'image, etc.

Je crois que vous devez vérifier certaines propriétés si Flash est pris en charge par le navigateur ou si le navigateur affiche une image ou non, ou peut-être souhaitez-vous vérifier la taille de l'écran,


vous pourriez en discuter dans les commentaires. Quoi qu'il en soit, il y a de nombreux cas à vérifier wevbview
Yozi
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.