web-dev-qa-db-fra.com

Détecter le navigateur Safari

Comment détecter le navigateur Safari en utilisant JavaScript? J'ai essayé le code ci-dessous et il détecte non seulement Safari mais également le navigateur Chrome.

function IsSafari() {

  var is_safari = navigator.userAgent.toLowerCase().indexOf('safari/') > -1;
  return is_safari;

}
99
Tomas

Vous pouvez facilement utiliser index of Chrome pour filtrer Chrome:

var ua = navigator.userAgent.toLowerCase(); 
if (ua.indexOf('safari') != -1) { 
  if (ua.indexOf('chrome') > -1) {
    alert("1") // Chrome
  } else {
    alert("2") // Safari
  }
}
82
david

Remarque: essayez toujours de détecter le comportement spécifique que vous essayez de corriger au lieu de le cibler avec isSafari?.

En dernier recours, détecte Safari avec cette expression rationnelle:

var isSafari = /^((?!chrome|Android).)*safari/i.test(navigator.userAgent);

Il utilise des regards négatifs et exclut les navigateurs Chrome, Edge et Android qui incluent le nom Safari dans leur agent utilisateur.

101
bfred.it

Comme d'autres personnes l'ont déjà noté, la détection des fonctionnalités est préférable à la recherche d'un navigateur spécifique. Une des raisons est que la chaîne de l'agent utilisateur peut être modifiée. Une autre raison est que la chaîne peut changer et casser votre code dans les versions les plus récentes.

Si vous voulez toujours le faire et tester une version de Safari, je vous suggère d'utiliser cette

var isSafari = navigator.vendor && navigator.vendor.indexOf('Apple') > -1 &&
               navigator.userAgent &&
               navigator.userAgent.indexOf('CriOS') == -1 &&
               navigator.userAgent.indexOf('FxiOS') == -1;

Cela fonctionnera avec toutes les versions de Safari sur tous les appareils: Mac, iPhone, iPod, iPad.

Modifier

Pour tester dans votre navigateur actuel: https://jsfiddle.net/j5hgcbm2/

Modifier 2

Mis à jour en fonction de Documents Chrome pour détecter correctement Chrome sur iOS

Il est à noter que tous les navigateurs sur iOS ne sont que des wrappers pour Safari et utilisent le même moteur. Voir le commentaire de bfred.it sur sa propre réponse dans ce fil.

Modifier 3

Mis à jour selon Firefox docs pour détecter correctement Firefox sur iOS

61
qingu

Il suffit d'utiliser:

var isSafari = window.safari !== undefined;
if (isSafari) console.log("Safari, yeah!");
25
lukyer

Ce code est utilisé pour détecter uniquement le navigateur safari

if (navigator.userAgent.search("Safari") >= 0 && navigator.userAgent.search("Chrome") < 0) 
{
   alert("Browser is Safari");          
}
18
wahid

Puisque userAgent pour chrome et safari sont presque identiques, il peut être plus facile de consulter le fournisseur du navigateur.

Safari

navigator.vendor ==  "Apple Computer, Inc."

Chrome

navigator.vendor ==  "Google Inc."

FireFox (pourquoi est-il vide?)

navigator.vendor ==  ""

IE(pourquoi est-ce indéfini?)

navigator.vendor ==  undefined
9
tylerlindell

Seulement Safari sans Chrome:

Après avoir essayé d'autres codes, je n'en ai trouvé aucun qui fonctionne avec les nouvelles et les anciennes versions de Safari.

Enfin, j'ai créé ce code qui fonctionne très bien pour moi:

var ua = navigator.userAgent.toLowerCase(); 
var isSafari = false;
try {
  isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || safari.pushNotification);
}
catch(err) {}
isSafari = (isSafari || ((ua.indexOf('safari') != -1)&& (!(ua.indexOf('chrome')!= -1) && (ua.indexOf('version/')!= -1))));

//test
if (isSafari)
{
  //Code for Safari Browser (Desktop and Mobile)
  document.getElementById('idbody').innerHTML = "This is Safari!";
}
else
{
  document.getElementById('idbody').innerHTML = "Not is Safari!";
}
<body id="idbody">
</body>

5
leoledmag

Je l'utilise

function getBrowserName() {
    var name = "Unknown";
    if(navigator.userAgent.indexOf("MSIE")!=-1){
        name = "MSIE";
    }
    else if(navigator.userAgent.indexOf("Firefox")!=-1){
        name = "Firefox";
    }
    else if(navigator.userAgent.indexOf("Opera")!=-1){
        name = "Opera";
    }
    else if(navigator.userAgent.indexOf("Chrome") != -1){
        name = "Chrome";
    }
    else if(navigator.userAgent.indexOf("Safari")!=-1){
        name = "Safari";
    }
    return name;   
}

if( getBrowserName() == "Safari" ){
    alert("You are using Safari");
}else{
    alert("You are surfing on " + getBrowserName(name));
}
3
lovepong

Je sais que cette question est ancienne, mais j'ai quand même pensé à poster la réponse car cela pourrait aider quelqu'un. Les solutions ci-dessus échouaient dans certains cas Edge. Nous avons donc dû les implémenter de manière à gérer séparément iOS, Desktop et d'autres plates-formes.

function isSafari() {
    var ua = window.navigator.userAgent;
    var iOS = !!ua.match(/iP(ad|od|hone)/i);
    var hasSafariInUa = !!ua.match(/Safari/i);
    var noOtherBrowsersInUa = !ua.match(/Chrome|CriOS|OPiOS|mercury|FxiOS|Firefox/i)
    var result = false;
    if(iOS) { //detecting Safari in IOS mobile browsers
        var webkit = !!ua.match(/WebKit/i);
        result = webkit && hasSafariInUa && noOtherBrowsersInUa
    } else if(window.safari !== undefined){ //detecting Safari in Desktop Browsers
        result = true;
    } else { // detecting Safari in other platforms
        result = hasSafariInUa && noOtherBrowsersInUa
    }
    return result;
}
1
H H

Je ne sais pas pourquoi l'OP voulait détecter Safari, mais dans les rares cas où vous avez besoin d'une détection de navigateur, il est probablement plus important de détecter le moteur de rendu que le nom du navigateur. Par exemple, sur iOS, tous les navigateurs utilisent le moteur Safari/Webkit. Il est donc inutile de choisir "chrome" ou "firefox" comme nom de navigateur si le rendu sous-jacent est en fait Safari/Webkit. Je n'ai pas testé ce code avec les anciens navigateurs, mais il fonctionne avec tout ce qui est récent sur Android, iOS, OS X, Windows et Linux.

<script>
    let browserName = "";

    if(navigator.vendor.match(/google/i)) {
        browserName = 'chrome/blink';
    }
    else if(navigator.vendor.match(/Apple/i)) {
        browserName = 'safari/webkit';
    }
    else if(navigator.userAgent.match(/firefox\//i)) {
        browserName = 'firefox/gecko';
    }
    else if(navigator.userAgent.match(/Edge\//i)) {
        browserName = 'Edge/edgehtml';
    }
    else if(navigator.userAgent.match(/trident\//i)) {
        browserName = 'ie/trident';
    }
    else
    {
        browserName = navigator.userAgent + "\n" + navigator.vendor;
    }
    alert(browserName);
</script>

Clarifier:

  • Tous les navigateurs sous iOS seront signalés comme "safari/webkit"
  • Tous les navigateurs sous Android, mais Firefox seront signalés comme "chrome/clignotement"
  • Chrome, Opera, Blisk, Vivaldi, etc. seront tous signalés comme "chrome/clignotement" sous Windows, OS X ou Linux.
1
Christopher Martin

Ce problème unique est à 100% le signe que le navigateur est Safari (croyez-le ou non).

if (Object.getOwnPropertyDescriptor(Document.prototype, 'cookie').descriptor === false) {
   console.log('Hello Safari!');
}

Cela signifie que le descripteur d'objet cookie a la valeur false sur Safari, tandis que tous les autres sont vrais, ce qui me donne vraiment mal à la tête sur l'autre projet. Bonne codage!

1
zoxxx

J'ai observé que seul un mot distingue Safari - "Version". Donc, cette expression rationnelle fonctionnera parfaitement:

/.*Version.*Safari.*/.test(navigator.userAgent)
1
Piotr Kowalski

Regex modifié pour répondre ci-dessus

var isSafari = /^((?!chrome|Android|crios|fxios).)*safari/i.test(navigator.userAgent);
  • crios - Chrome 
  • fxios - Firefox
1
Yurii Sherbak

Pour les enregistrements, le moyen le plus sûr que j’ai trouvé est d’implémenter la partie Safari du code de détection de navigateur à partir de cette réponse :

const isSafari = window['safari'] && safari.pushNotification &&
    safari.pushNotification.toString() === '[object SafariRemoteNotification]';

Bien entendu, le meilleur moyen de traiter les problèmes propres au navigateur est de toujours effectuer la détection des fonctionnalités, dans la mesure du possible. Utiliser un morceau de code comme celui ci-dessus est, cependant, toujours meilleur que la détection de chaîne d'agent.

0
Marcos Sandrini

Peut-être que cela fonctionne:

Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor')

EDIT: NE TRAVAILLE PLUS

0