Safari-Browser erkennen

142

Wie erkenne ich einen Safari-Browser mit JavaScript? Ich habe den folgenden Code ausprobiert und er erkennt nicht nur Safari, sondern auch den Chrome-Browser.

function IsSafari() {

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

}
Tomas
quelle
1
Ein Teil des JS-Codes, der sich auf das Senden von Dateien bezieht, funktioniert für Safari respektvoll, für Chrome funktioniert es einwandfrei.
Tomas
1
Sie sollten mit ziemlicher Sicherheit auf Unterschiede in den vorhandenen APIs testen. Es gibt andere WebKit-basierte Browser als Safari und Chrome.
Quentin
12
Es gibt viele Gründe, warum man den Browser erkennen möchte. Zum Beispiel sind zum jetzigen Zeitpunkt bestimmte Aspekte der SVG-Engine, wie z. B. Filter, in Safari defekt, funktionieren jedoch in Chrome.
Paul Legato
Manchmal kann man den Fehler einfach nicht beheben, weil man ihn nicht reproduzieren kann (ich habe keinen Zugriff auf den Mac). Ich habe ein Problem mit Midori behoben (ein BlobBuilder / Blob-Problem für sendAsBinary shim), aber der Client sagt, dass es immer noch ein Problem mit dem Hochladen von Dateien gibt. Das Beste, was ich mir vorstellen kann, ist, die Safari-Unterstützung zu entfernen und iframes dafür zu verwenden (wie für alter IE)
llamerr

Antworten:

110

Sie können den Chrome-Index ganz einfach verwenden, um Chrome herauszufiltern:

var ua = navigator.userAgent.toLowerCase(); 
if (ua.indexOf('safari') != -1) { 
  if (ua.indexOf('chrome') > -1) {
    alert("1") // Chrome
  } else {
    alert("2") // Safari
  }
}
David
quelle
6
Funktioniert nicht Derzeit wird eine Chrome-UA-Zeichenfolge auf dem iPhone ausgegeben, und es ist nicht einmal das Wort "Chrome" enthalten.
Paul Carlton
5
IE 11 UA String in Windows 10 enthält auch Safari und Chrome
Cuixiping
Blackberry enthält auch "Safari".
Harry Pehkonen
18
@Flimm Es gibt viele legitime Anwendungsfälle für die Browsererkennung. Nehmen Sie nicht an, die Absicht des Fragestellers oder des Antwortenden zu kennen. Es ist zwar großartig, einen hilfreichen Tipp beizufügen, von dem Sie glauben, dass er relevant ist, aber es ist keineswegs eine Anforderung.
Ruben Martinez Jr.
1
Dies funktioniert nicht in Android-Browsern, die "Safari", aber nicht "Chrome" enthalten: developer.whatismybrowser.com/useragents/explore/software_name/…
Eric Andrew Lewis
156

Hinweis: Versuchen Sie immer, das spezifische Verhalten zu erkennen, das Sie beheben möchten, anstatt es gezielt einzusetzenisSafari?

Als letzten Ausweg erkennen Sie Safari mit diesem regulären Ausdruck:

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

Es verwendet negative Look-arounds und schließt Chrome, Edge und alle Android-Browser aus, die den SafariNamen in ihrem Benutzeragenten enthalten.

fregante
quelle
2
Das funktioniert nicht. Ich werde immer noch wahr, wenn ich Chrome Browser auf einem iPhone verwende.
Ayjay
27
Dies liegt daran, dass alle Browser unter iOS nur Wrapper für Safari sind (mit Ausnahme von Opera Mini im Mini- Modus), einschließlich Chrome. Dies bedeutet nicht unbedingt, dass alle mit diesem Test übereinstimmen, da die userAgent-Zeichenfolge dem Wrapper entspricht. Möglicherweise möchten Sie Chrome unter iOS separat erkennen.
fregante
Alter, das hat bei mir funktioniert !!! Vielen Dank. Navigator.userAgent hat Werte wie "5.0 (Windows NT 6.1) AppleWebKit / 537.36 (KHTML, wie Gecko) Chrome / 39.0.2171.99 Safari / 537.36" für Chrome in Windows und Safari in Mac zurückgegeben.
KaustubhSV
2
Jetzt behoben. Sie haben definitiv Recht, das Problem bei vielen Browsern ist, dass sie andere Namen enthalten, um nicht ausgelassen zu werden. Like Edge enthält sowohl Chrome als auch Safari in seiner UA. Benutzeragentenprüfungen sind aus diesem Grund schlecht: Browser ändern sich und die Prüfungen müssen aktualisiert werden. Leider gibt es keine perfekte Möglichkeit, einen Browser zu erkennen, es ist immer eine Vermutung.
fregante
1
Auf jeden Fall eine gute Idee, die Funktionserkennung zu verwenden, aber einige Verhaltensweisen sind nur schwer oder fast unmöglich zu testen, z. B. ob Videos auf Mobilgeräten automatisch im Vollbildmodus angezeigt werden, was nur auf dem iPhone und dem iPod der Fall ist. Um es zu testen, müssen Sie ein Video laden und vom Benutzer abspielen lassen.
Fregante
91

Wie bereits erwähnt, wird die Funktionserkennung der Suche nach einem bestimmten Browser vorgezogen. Ein Grund ist, dass die Benutzeragentenzeichenfolge geändert werden kann. Ein weiterer Grund ist, dass sich die Zeichenfolge in neueren Versionen möglicherweise ändert und Ihren Code beschädigt.

Wenn Sie es dennoch tun und auf eine Safari-Version testen möchten, würde ich empfehlen, diese zu verwenden

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

Dies funktioniert mit jeder Version von Safari auf allen Geräten: Mac, iPhone, iPod, iPad.

Bearbeiten

So testen Sie in Ihrem aktuellen Browser: https://jsfiddle.net/j5hgcbm2/

Bearbeiten 2

Aktualisiert gemäß Chrome-Dokumenten , um Chrome unter iOS korrekt zu erkennen

Es ist erwähnenswert, dass alle Browser unter iOS nur Wrapper für Safari sind und dieselbe Engine verwenden. Siehe den Kommentar von bfred.it zu seiner eigenen Antwort in diesem Thread.

Bearbeiten 3

Aktualisiert gemäß den Firefox-Dokumenten , um Firefox unter iOS korrekt zu erkennen

qingu
quelle
Vielen Dank für den Kommentar - Aktualisiert, um Chrome unter iOS korrekt zu erkennen
Qingu
@qingu - Ich verstehe dieses Javascript nicht, wie würde ich so etwas machen - wenn (safaribrowser) {mach das} sonst {mach das} mit dem gleichen Code, welcher Wert ist 'var isSafari' danke
GAV
@GAV: isSafariwird sonst truein einem Safari-Browser sein false. Sie können einfach das obige Snippet verwenden und dann Ihr Snippet fast so verwenden, wie Sie es gepostet haben. if (isSafari) { do_this(); } else { do_that(); }.
Qingu
2
Leider gibt es mehr Gründe, den Browser herauszufinden, als nur die Funktionserkennung. Ein Browser kann eine Funktion unterstützen, ist jedoch fehlerhaft (z. B. Canvas-Fehler in IE10, aber dieselbe Funktion funktioniert in IE9). Außerdem verhält sich Firefox anders als Webkit-basierte Browser, z. B. wie es auf Mausbewegungen reagiert. Apples Safari weist Reflow-Fehler auf, die in Chrome nicht vorhanden sind. Einige Browser sind auch bei bestimmten rechenintensiven Aufgaben leistungsfähiger als andere.
DemiImp
2
@Andras Für Firefox können Sie && !navigator.userAgent.match('FxiOS')ähnlich wie die Chrome-Prüfung hinzufügen - ref ( developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/… )
Petri Pellinen
58

Benutz einfach:

var isSafari = window.safari !== undefined;
if (isSafari) console.log("Safari, yeah!");
lukyer
quelle
15
Ich bin mir nicht sicher, warum dies nicht weiter oben liegt - ist dies perfekt, kurz und einfach? Ich musste Desktop-Safari aus Mangel an ausschließen getUserMedia.
Stephen Tetreault
3
Dies ist der perfekte Weg, um Desktop-Safari zu bestimmen, da dies nicht auf Mobilgeräten
funktioniert
Für welche Versionen von Safari funktioniert dies? Scheint nicht für v5.1.7 zu funktionieren
ElliotSchmelliot
Wenn Sie sich nur für Browser interessieren und nicht für Mobilgeräte oder Desktops, funktioniert dies einwandfrei.
Antuan
1
Dies funktionierte nicht in iPhone 11 Pro Max Simulator 13.5
Christian Valentin
19

Dieser Code wird verwendet, um nur Safari-Browser zu erkennen

if (navigator.userAgent.search("Safari") >= 0 && navigator.userAgent.search("Chrome") < 0) 
{
   alert("Browser is Safari");          
}
Wahid
quelle
4
Dieser Code erkennt nur, ob ein Webkit-Browser nicht verchromt ist. Viele andere Browser haben die schlechte Idee, "Safari" in ihre Benutzeragentenzeichenfolge aufzunehmen. Zum Beispiel Opera: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36 OPR/24.0.1558.51 (Edition Next)oder Stock Android Browser:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.34 Safari/534.24
Rupps
Durch das Erkennen der Plattformerkennung können möglicherweise bestimmte Kompatibilitätsfälle herausgefiltert werden.
ljgww
Ich habe gerade ein halbes Dutzend iOS-Browser von Drittanbietern überprüft, die alle den sehr genauen Safari User-Agent fälschen.
Mitch Match
Dies erkennt also nur Chrome. Und doch habe ich gerade herausgefunden, dass Chrome 44 kein Chrome mehr in der UA hat, sondern 'CriOS' :(
Mitch Match
Wir sollten immer versuchen, die Funktionserkennung durchzuführen und die Browsererkennung als letzten Ausweg zu verwenden, da letztere viel wahrscheinlicher dazu führen, dass legitime Benutzer beschädigt werden und blockiert werden. Jede Antwort, in der die Erkennung von Funktionen überhaupt nicht erwähnt wird, wird von mir abgelehnt.
Flimm
12

Da userAgent für Chrome und Safari nahezu identisch sind, kann es einfacher sein, den Anbieter des Browsers zu ermitteln

Safari

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

Chrom

navigator.vendor ==  "Google Inc."

FireFox (warum ist es leer?)

navigator.vendor ==  ""

IE (warum ist es undefiniert?)

navigator.vendor ==  undefined
tylerlindell
quelle
1
Ich suchte nach etwas, um Warnmeldungen in Safari bei der Arbeit auf verschiedenen Computern (Mac-Desktops, iPads usw.) zu deaktivieren, und dies funktionierte perfekt.
dylnmc
Der Anbieter für Chrome unter iOS wird jedoch auch "Apple Computer, Inc." sein. Entschuldigung ...
Piotr Kowalski
@PiotrKowalski - mit welcher Lösung haben Sie sich entschieden?
Tylerlindell
@tylerlindell Siehe meine Antwort am Ende dieser Seite mit dem Wort "Version".
Piotr Kowalski
7

Nur Safari ohne Chrome:

Nachdem ich andere Codes ausprobiert hatte, fand ich keine, die mit neuen und alten Versionen von Safari funktioniert.

Schließlich habe ich diesen Code gemacht, der für mich sehr gut funktioniert:

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>

leoledmag
quelle
5

Ich habe festgestellt, dass nur ein Wort Safari unterscheidet - "Version". Dieser Regex wird also perfekt funktionieren:

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

Ich weiß nicht, warum das OP Safari erkennen wollte, aber in seltenen Fällen ist es heutzutage wahrscheinlich wichtiger, die Render-Engine zu erkennen als den Namen des Browsers. Unter iOS verwenden beispielsweise alle Browser die Safari / Webkit-Engine. Daher ist es sinnlos, "Chrome" oder "Firefox" als Browsernamen zu verwenden, wenn der zugrunde liegende Renderer tatsächlich Safari / Webkit ist. Ich habe diesen Code nicht mit alten Browsern getestet, aber er funktioniert mit allem, was unter Android, iOS, OS X, Windows und Linux ziemlich neu ist.

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

Zu klären:

  • Alle Browser unter iOS werden als "Safari / Webkit" gemeldet.
  • Alle Browser unter Android außer Firefox werden als "Chrome / Blink" gemeldet.
  • Chrome, Opera, Blisk, Vivaldi usw. werden unter Windows, OS X oder Linux als "Chrome / Blink" gemeldet
Christopher Martin
quelle
4

ich benutze das

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));
}
Liebespong
quelle
4

Einfachste Antwort:

function isSafari() {
 if (navigator.vendor.match(/[Aa]+pple/g).length > 0 ) 
   return true; 
 return false;
}
SudarP
quelle
2
Es funktioniert, obwohl es ohne regulären navigator.vendor.toLowerCase().indexOf('apple') > -1
Ausdruck
5
Noch einfacher ... if (navigator.vendor.match(/apple/i)) { ... }.
Brad
Das funktioniert nicht für ios 13.3.1 auf firefox , wie es Apple Computer zeigt, inc
nuttynibbles
1
@nuttynibbles: Dies ist wahrscheinlich das, was Sie wollen, weil jeder Browser unter iOS eine Safari in Verkleidung ist.
Wortwart
3

Für die Datensätze ist der sicherste Weg, den ich gefunden habe, den Safari-Teil des Browser-Erkennungscodes aus dieser Antwort zu implementieren :

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

Der beste Weg, um mit browserspezifischen Problemen umzugehen, ist natürlich immer die Feature-Erkennung, wenn dies überhaupt möglich ist. Die Verwendung eines Codeteils wie des oben genannten ist jedoch immer noch besser als die Erkennung von Agentenzeichenfolgen.

Marcos Sandrini
quelle
1
Dies funktioniert nicht mit Safari Version / 13.1 Mobile / 15E148 Safari / 604.1 unter iPhone OS 13_4_1.
Mindo
2

Ich weiß, dass diese Frage alt ist, aber ich dachte trotzdem daran, die Antwort zu veröffentlichen, da sie jemandem helfen könnte. Die oben genannten Lösungen scheiterten in einigen Randfällen, sodass wir sie so implementieren mussten, dass iOS, Desktop und andere Plattformen separat behandelt werden.

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;
}
HH
quelle
1

Modifizierter regulärer Ausdruck für die Antwort oben

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

Dieses einzigartige "Problem" ist ein 100% iges Zeichen dafür, dass es sich bei dem Browser um Safari handelt (ob Sie es glauben oder nicht).

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

Dies bedeutet, dass der Cookie-Objektdeskriptor auf Safari auf false gesetzt ist, während auf allen anderen true, was mir beim anderen Projekt tatsächlich Kopfschmerzen bereitet. Viel Spaß beim Codieren!

zoxxx
quelle
Scheint nicht mehr wahr zu sein. Stürzt auch in Firefox ab "Object.getOwnPropertyDescriptor (...) is undefined"
Offirmo
0

Vielleicht funktioniert das:

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

EDIT: NICHT MEHR ARBEITEN

Harshal Carpenter
quelle
Was genau macht das, weil in allen Browsern -1 zurückgegeben wird?
Petroff
@Petroff es funktioniert nicht mehr in neueren Safari. Vielen Dank für den Hinweis.
Harshal Carpenter
2
Fühlen Sie sich frei, die Antwort zu löschen.
Flimm
0

Ich erstelle eine Funktion, die einen booleschen Typ zurückgibt:

export const isSafari = () => navigator.userAgent.toLowerCase().indexOf('safari') !== -1
Idan
quelle
-2

Das Schnüffeln von Benutzeragenten ist wirklich schwierig und unzuverlässig. Wir haben versucht, Safari unter iOS mit der obigen Antwort von @ qingu zu erkennen. Für Safari, Chrome und Firefox hat es ziemlich gut funktioniert. Aber es hat Opera und Edge fälschlicherweise als Safari erkannt.

Daher haben wir uns für die Feature-Erkennung entschieden, die ab heute serviceWorkernur in Safari und in keinem anderen Browser unter iOS unterstützt wird. Wie in https://jakearchibald.github.io/isserviceworkerready/ angegeben

Der Support umfasst keine iOS-Versionen von Browsern von Drittanbietern auf dieser Plattform (siehe Safari-Unterstützung).

Also haben wir so etwas gemacht

if ('serviceWorker' in navigator) {
    return 'Safari';
}
else {
    return 'Other Browser';
}

Hinweis : Nicht unter Safari unter MacOS getestet.

AG
quelle