Stellen Sie fest, ob der Benutzer von Mobile Safari aus navigiert hat

71

Ich habe eine App und möchte die Benutzer auf verschiedene Seiten umleiten, je nachdem, von wo aus sie navigieren.

Wenn Sie von einem Webclip aus navigieren, leiten Sie nicht um. Wenn Sie von Mobile Safari aus navigieren, leiten Sie zu safari.aspx weiter. Wenn Sie von einem anderen Ort aus navigieren, leiten Sie zu unavailable.aspx um

Ich konnte iPhone-Webanwendungen verwenden. Gibt es eine Möglichkeit, festzustellen, wie sie geladen wurden? Startbildschirm vs Safari? um festzustellen, ob der Benutzer von einem Webclip aus navigiert hat, aber ich habe Probleme festzustellen, ob der Benutzer von Mobile Safari auf einem iPhone oder iPod navigiert hat.

Folgendes habe ich:

if (window.navigator.standalone) {
    // user navigated from web clip, don't redirect
}
else if (/*logic for mobile Safari*/) {
    //user navigated from mobile Safari, redirect to safari page
    window.location = "safari.aspx";
}
else {
    //user navigated from some other browser, redirect to unavailable page
    window.location = "unavailable.aspx";
}
Steven
quelle
@Ali diese Frage verlangt nicht das Gleiche wie diese
Jake Millington

Antworten:

30

UPDATE : Dies ist eine sehr alte Antwort und ich kann sie nicht löschen, da die Antwort akzeptiert wird. Überprüfen Sie die Antwort von unwitting unten, um eine bessere Lösung zu finden.


Sie sollten in der Benutzeragentenzeichenfolge nach dem Teilstring "iPad" oder "iPhone" suchen können :

var userAgent = window.navigator.userAgent;

if (userAgent.match(/iPad/i) || userAgent.match(/iPhone/i)) {
   // iPad or iPhone
}
else {
   // Anything else
}
Daniel Vassallo
quelle
11
Ich denke es ist nicht. Wie wäre es anders als Safari iOS Browser? Ich denke, dieser Ausdruck schließt nicht nur Safari aus, sondern alle iPhone / iPad-Browser.
Kamilius
16
Dies ist nicht die richtige Antwort, denn wenn ich von Chrome für
iOS darauf
7
Dies funktioniert nicht, da der Benutzer jetzt möglicherweise mit Mobile Chrome unter iOS surft und dies dennoch wahr ist, obwohl es sich nicht um Mobile Safari handelt.
Jangosteve
2
Dadurch wird nicht erkannt, ob der Benutzer beispielsweise mobiles Chrome verwendet. Und Chrome iOS verfügt im Vergleich zu Safari über eine sehr alte Javascript-Engine (aufgrund der Richtlinien von Apple), die ein gewisses Rendern unmöglich macht.
Aero Wang
2
Dies sollte nicht als richtige Antwort markiert werden, da es einen Browser enthält, der auf dem iPhone ausgeführt wird. Die Frage stellt speziell, um mobile Safari zu erkennen.
Shashank
165

Siehe https://developer.chrome.com/multidevice/user-agent#chrome_for_ios_user_agent - Die Benutzeragentenzeichenfolgen für Safari unter iOS und Chrome unter iOS sind ungünstig ähnlich:

Chrom

Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3

Safari

Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543 Safari/419.3

Es sieht so aus, als ob der beste Ansatz hier darin besteht, zunächst nach iOS zu suchen, wie andere Antworten vorgeschlagen haben, und dann nach den Dingen zu filtern, die die Safari UA einzigartig machen. Ich würde vorschlagen, dass dies am besten mit "ist AppleWebKit und ist nicht CriOS" erreicht wird:

var ua = window.navigator.userAgent;
var iOS = !!ua.match(/iPad/i) || !!ua.match(/iPhone/i);
var webkit = !!ua.match(/WebKit/i);
var iOSSafari = iOS && webkit && !ua.match(/CriOS/i);
unwissend
quelle
1
@ Fabricioflores c'est la vie :(
unwissentlich
7
+1 Die einzige Antwort hier, die alle Spezifikationen abdeckte. Ich würde nur den regulären Regex für iOS-Tests in ändern, /iP(ad|hone)/idamit Sie das oder nicht benötigen.
Sareed
2
@sareed Ich fand es immer erstaunlich befriedigend, iP (ad | od | hone) regexen zu können
unwissentlich
8
Stupid Opera unter iOS würde den obigen Code immer noch als wahr übergeben, daher habe ich die letzte Zeile in folgende geändert: var iOSSafari = iOS && Webkit &&! Ua.match (/ CriOS / i) &&! Ua.match (/ OPiOS / i) ;;
Hooman Askari
3
Gute Antwort. Aber warum ein doppeltes Negativ (!!) mit Übereinstimmung verwenden, wenn Sie test () verwenden können?
OMA
27

Best Practice ist:

function isMobileSafari() {
    return navigator.userAgent.match(/(iPod|iPhone|iPad)/) && navigator.userAgent.match(/AppleWebKit/)
}
appsthatmatter
quelle
25
Das würde auch für Chrome iOS passen
httpete
Dies erkennt auch mobiles Chrom.
Sean
Wie sollen wir dann zwischen iOS Safari und iOS Chrome unterscheiden? Irgendwelche Ideen?
Burak Karakuş
Diese beiden regulären Ausdrücke können leicht kombiniert werden
Antoine129
Dies passt auch zu Desktop Safari.
Antoine129
7

Fallender Code findet nur mobile Safari und nichts anderes (außer Delphin und anderen kleinen Browsern)

  (/(iPad|iPhone|iPod)/gi).test(userAgent) &&
  !(/CriOS/).test(userAgent) &&
  !(/FxiOS/).test(userAgent) &&
  !(/OPiOS/).test(userAgent) &&
  !(/mercury/).test(userAgent)
aWebDeveloper
quelle
1
Dies ist die einzige, die Firefox und Opera unter iOS unterscheidet.
Nord-Stream
5

Alle Antworten und Kommentare zusammengeführt. Und das ist das Ergebnis.

function iOSSafari(userAgent)
{
    return /iP(ad|od|hone)/i.test(userAgent) && /WebKit/i.test(userAgent) && !(/(CriOS|FxiOS|OPiOS|mercury)/i.test(userAgent));
}



var iOSSafari = /iP(ad|od|hone)/i.test(window.navigator.userAgent) && /WebKit/i.test(window.navigator.userAgent) && !(/(CriOS|FxiOS|OPiOS|mercury)/i.test(window.navigator.userAgent));
Константин Ван
quelle
Ich WebKit
vermute,
1
@ antoine129 Nein, tut es nicht (getestet unter OS X El Capitan) - die regulären Ausdrücke sind ANDed und ich denke, Desktop Safari sendet nie iP * ...
Christian Ulbrich
5

Nach all den Antworten finden Sie hier einige Tipps zu den vorgeschlagenen RegExes:

  • AppleWebKit passt auch zu Desktop Safari (nicht nur mobil)
  • Sie müssen nicht .matchmehr als einmal für solche einfachen regulären Ausdrücke aufrufen und bevorzugen die leichtere .testMethode.
  • Das g(globale) Regex-Flag ist nutzlos, während das i(ohne Berücksichtigung der Groß- und Kleinschreibung) nützlich sein kann
  • Keine Notwendigkeit für die Erfassung (Klammern), wir testen nur die Zeichenfolge

Ich benutze dies nur, da es truefür mich in Ordnung ist, für Mobile Chrome zu werden (gleiches Verhalten):

/iPhone|iPad|iPod/i.test(navigator.userAgent)

(Ich möchte nur erkennen, ob das Gerät ein Ziel für eine iOS-App ist.)

Antoine129
quelle
2
Wichtige Anmerkungen zu den regulären Ausdrücken (im Allgemeinen), danke, dass Sie hier darauf hingewiesen haben (wo die meisten es falsch verstanden haben)! Zusätzlich zu Ihrer Antwort sollte heutzutage auch geprüft werden, ob !window.MSStreamdie Browser von Microsoft gemäß dieser Antwort auf eine andere Frage ausgeschlossen werden sollen. Und !/CriOS/.test(navigator.userAgent)ist für diejenigen, die möchten, dass Chrome gemäß dieser Antwort herausgefiltert wird .
Caw
1

Tatsächlich gibt es keine Silberkugel für die Erkennung mobiler Safari. Es gibt einige Browser, die möglicherweise die Schlüsselwörter des Benutzeragenten von Mobile Safari verwenden. Möglicherweise können Sie die Funktionserkennung versuchen und die Regel ständig aktualisieren.

Licht
quelle
1
Nein in meinem Fall zum Beispiel. Ich möchte ein benutzerdefiniertes Smart-Banner für iOS + Chrome anzeigen, dieses Banner jedoch nicht für iOS + Safari, da iOS + Safari bereits über ein integriertes Smart-Banner verfügt.
JobaDiniz
@JobaDiniz Ich weiß, dass viele Leute etwas nur in der mobilen Safari tun wollen, aber nicht in anderen Browsern. Ich auch. Browser, die mit Token wie "iPad", "iOS", "iPhone" usw. übereinstimmen Das heißt nicht, dass es sich um eine mobile Safari handelt, vielleicht sind es auch andere Browser für iOS. Zum Beispiel UC- und QQ-Browser in China. Alle diese Browser verwenden möglicherweise den Kern der Safari und die meisten Verhaltensweisen entsprechen denen der mobilen Safari, einige jedoch nicht. Es nervt.
Licht
Es ist in der Tat scheiße. Dumm von mir hatte ich gehofft, dass navigator.appname anders sein würde, alle iOS-Browser sind 'Netscape'. Safari ist jedoch die einzige, die Konfigurationsprofile installieren kann. Wenn also eine andere Person eine .mobileconfig erhält, lädt sie diese herunter und sieht dumm aus, weil sie nicht weiß, welche App sie öffnen kann ...
Mitch Match
1

Ich weiß, dass dies ein alter Thread ist, aber ich möchte meine Lösung mit euch teilen.

Ich musste erkennen, wann ein Benutzer von Desktop Safari aus navigiert (weil wir Mitte 2017 sind und Apple noch keine Unterstützung für input[type="date"]...

Also habe ich einen benutzerdefinierten Fallback-Datepicker dafür erstellt. Dies gilt jedoch nur für Safari auf dem Desktop, da dieser Eingabetyp in Mobile Safari einwandfrei funktioniert. Also habe ich diesen Regex gemacht, um nur Desktop-Safari zu erkennen. Ich habe es bereits getestet und es passt nicht zu Opera, Chrome, Firefox oder Safari Mobile.

Hoffe, es kann einigen von euch helfen.

if(userAgent.match(/^(?!.*chrome).(?!.*mobile).(?!.*firefox).(?!.*iPad).(?!.*iPhone).*safari.*$/i)){
  $('input[type="date"]').each(function(){
    $(this).BitmallDatePicker();
  })
}
edd2110
quelle
1

Ich habe die Antwort von @unwitting positiv bewertet, da sie mich unweigerlich in Schwung gebracht hat. Beim Rendern meines SPA in einer iOS-Webansicht musste ich es jedoch etwas anpassen.

function is_iOS () {
    /*
        Returns (true/false) whether device agent is iOS Safari
    */
    var ua = navigator.userAgent;
    var iOS = !!ua.match(/iPad/i) || !!ua.match(/iPhone/i);
    var webkitUa = !!ua.match(/WebKit/i);

    return typeof webkitUa !== 'undefined' && iOS && webkitUa && !ua.match(/CriOS/i);
};

Der Hauptunterschied besteht in der Umbenennung von webkitin webkitUa, um Konflikte mit dem webkitStammobjekt zu vermeiden, das als Nachrichtenhandler zwischen SPA und UIView verwendet wird.

pim
quelle
Das hat funktioniert. Rückgabetyp von webkitUa! == 'undefined' && iOS && webkitUa &&! ua.match (/ CriOS / i);
Vignesh Chinnaiyan
0
function isIOS {
  var ua = window.navigator.userAgent;
  return /(iPad|iPhone|iPod).*WebKit/.test(ua) && !/(CriOS|OPiOS)/.test(ua);
}
Kugutsumen
quelle
0

Ich suchte nach dieser Antwort und erinnerte mich, dass ich darauf schon einmal gestoßen war.

Der zuverlässigste Weg, um Safari unter iOS in JavaScript zu erkennen, ist

if (window.outerWidth === 0) {
    // Code for Safari on iOS
} 

or 

if (window.outerHeight === 0) {
    // Code for Safari on iOS
} 

Aus irgendeinem Grund gibt Safari unter iOS 0 für die Eigenschaften window.outerHeight und window.outerWidth zurück.

Dies gilt für alle iPads und iPhones aller iOS-Versionen. Jeder andere Browser und jedes andere Gerät dieser Eigenschaft funktioniert normal.

Ich bin mir nicht sicher, ob sie dies ändern wollen, aber im Moment funktioniert es gut.

naeluh
quelle
0

Diese Regex funktioniert für mich, sauber und einfach

const isIOSSafari = !! window.navigator.userAgent.match (/ Version / [\ d.] +. * Safari /);

Cyanit
quelle
Dies funktioniert mit eingebettetem WKWebView nicht, wenn die Host-App nicht explizit Safarizu einer benutzerdefinierten Benutzeragentenzeichenfolge hinzugefügt wird.
mrgrieves
iPad Safari lügt jetzt standardmäßig.
Csaba Toth