Deteksi browser Safari

155

Bagaimana cara mendeteksi browser Safari menggunakan JavaScript? Saya telah mencoba kode di bawah ini dan tidak hanya mendeteksi Safari tetapi juga browser Chrome.

function IsSafari() {

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

}
Tomas
sumber
1
Beberapa kode JS yang terkait dengan pengiriman file berfungsi secara berbeda untuk Safari, untuk Chrome berfungsi dengan baik.
Tomas
1
Anda hampir pasti harus menguji perbedaan apa pun dalam API yang ada. Ada browser berbasis WebKit lain di luar Safari dan Chrome.
Quentin
12
Ada banyak alasan seseorang mungkin ingin mendeteksi browser. Misalnya, saat tulisan ini dibuat, aspek tertentu dari mesin SVG seperti filter rusak di Safari, tetapi berfungsi di Chrome.
Paul Legato
Terkadang Anda tidak dapat memperbaiki bug karena Anda tidak dapat mereproduksinya (saya tidak memiliki akses ke Mac). Saya memperbaiki masalah pada Midori (beberapa masalah BlobBuilder / Blob untuk sendAsBinary shim), tetapi klien mengatakan masih ada masalah dengan unggahan file, jadi hal terbaik yang dapat saya pikirkan hanyalah menghapus dukungan Safari dan menggunakan iframe untuk itu (seperti untuk IE lama)
llamerr
1
kemungkinan duplikat dari Cara mendeteksi browser chrome dan safari (webkit)
anik4e

Jawaban:

114

Anda dapat dengan mudah menggunakan indeks Chrome untuk memfilter Chrome:

var ua = navigator.userAgent.toLowerCase(); 
if (ua.indexOf('safari') != -1) { 
  if (ua.indexOf('chrome') > -1) {
    alert("1") // Chrome
  } else {
    alert("2") // Safari
  }
}
David
sumber
6
Tidak berhasil. Saat ini mengeluarkan string UA chrome di iPhone dan bahkan tidak ada kata "chrome" di dalamnya.
Paul Carlton
7
String IE 11 UA di Windows 10 juga berisi Safari dan Chrome
cuixiping
20
@Flimm Ada banyak kasus penggunaan yang sah untuk deteksi browser. Jangan berasumsi mengetahui maksud penanya atau penjawab. Meskipun bagus untuk menyertakan tip bermanfaat yang mungkin Anda yakini relevan, itu sama sekali bukan persyaratan.
Ruben Martinez Jr.
1
Ini tidak berfungsi pada browser Android, yang menyertakan "safari" tetapi tidak "chrome": developers.whatismybrowser.com/useragents/explore/software_name/…
Eric Andrew Lewis
1
Suara negatif, sebagai solusi yang tidak dapat diandalkan - jawaban yang lebih baik di bawah.
Oli C
164

Catatan: selalu coba untuk mendeteksi perilaku tertentu yang Anda coba perbaiki, alih-alih menargetkannyaisSafari?

Sebagai upaya terakhir, deteksi Safari dengan regex ini:

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

Ini menggunakan tampilan negatif dan mengecualikan Chrome, Edge, dan semua browser Android yang menyertakan Safarinama di agen penggunanya.

fregante
sumber
2
Ini tidak berhasil. Saya masih mengerti jika saya menggunakan Browser Chrome di iPhone.
ayjay
29
Itu karena semua browser di iOS hanyalah pembungkus untuk Safari (dengan pengecualian Opera Mini dalam mode Mini ), termasuk Chrome. Ini tidak berarti bahwa mereka semua akan cocok dengan pengujian ini karena string userAgent tergantung pada pembungkusnya. Anda mungkin ingin mendeteksi Chrome di iOS secara terpisah.
fregante
Bung, ini berhasil untukku !!! Terima kasih banyak .. navigator.userAgent mengembalikan nilai seperti "5.0 (Windows NT 6.1) AppleWebKit / 537.36 (KHTML, seperti Gecko) Chrome / 39.0.2171.99 Safari / 537.36" untuk Chrome di Windows dan Safari di mac.
KaustubhSV
2
Diperbaiki sekarang. Anda pasti benar, masalah dengan banyak browser adalah mereka menyertakan nama lain agar tidak ketinggalan. Like Edge menyertakan Chrome dan Safari di UA-nya. Pemeriksaan agen pengguna buruk karena alasan ini: browser berubah dan pemeriksaan perlu diperbarui. Sayangnya tidak ada cara sempurna untuk mendeteksi browser, itu selalu tebakan.
fregante
1
Jelas merupakan ide yang bagus untuk menggunakan deteksi fitur, tetapi beberapa perilaku sulit atau hampir tidak mungkin untuk diuji, misalnya apakah video di ponsel otomatis menjadi layar penuh, sesuatu yang hanya terjadi di iPhone dan iPod. Untuk mengujinya, Anda perlu memuat video dan meminta pengguna memutarnya.
fregante
96

Seperti yang telah diketahui orang lain, deteksi fitur lebih disukai daripada memeriksa browser tertentu. Salah satu alasannya adalah string agen pengguna dapat diubah. Alasan lainnya adalah string dapat berubah dan merusak kode Anda di versi yang lebih baru.

Jika Anda masih ingin melakukannya dan menguji versi Safari apa pun, saya sarankan untuk menggunakan ini

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

Ini akan bekerja dengan semua versi Safari di semua perangkat: Mac, iPhone, iPod, iPad.

Edit

Untuk menguji di browser Anda saat ini: https://jsfiddle.net/j5hgcbm2/

Edit 2

Diperbarui sesuai dengan dokumen Chrome untuk mendeteksi Chrome di iOS dengan benar

Perlu dicatat bahwa semua Browser di iOS hanyalah pembungkus untuk Safari dan menggunakan mesin yang sama. Lihat komentar bfred.it tentang jawabannya sendiri di utas ini.

Edit 3

Diperbarui sesuai dengan dokumen Firefox untuk mendeteksi Firefox di iOS dengan benar

qingu
sumber
Terima kasih atas komentarnya - Diperbarui untuk mendeteksi Chrome di iOS dengan benar
qingu
@qingu - Saya tidak mengerti javascript ini, bagaimana saya melakukan sesuatu seperti - jika (safaribrowser) {do this} else {do ​​that} menggunakan kode yang sama apa nilainya 'var isSafari' terima kasih
GAV
@GAV: isSafariakan ada truedi browser Safari, falsejika tidak. Anda cukup menggunakan potongan di atas dan kemudian menggunakan milik Anda hampir seperti yang Anda posting. if (isSafari) { do_this(); } else { do_that(); }.
qingu
2
Sayangnya, ada lebih banyak alasan untuk mencoba mencari tahu peramban daripada sekadar deteksi fitur. Browser dapat mendukung suatu fitur, tetapi dapat bermasalah (mis: bug kanvas di IE10, tetapi fitur yang sama berfungsi di IE9). Firefox juga berperilaku berbeda dari browser berbasis webkit, seperti responsnya terhadap gerakan mouse. Safari Apple memiliki bug reflow yang tidak ada di Chrome. Beberapa browser juga berfungsi saat melakukan tugas intensif komputasi tertentu daripada yang lain.
DemiImp
2
@Andras Untuk Firefox Anda dapat menambahkan yang && !navigator.userAgent.match('FxiOS')serupa dengan pemeriksaan Chrome - ref ( developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/… )
Petri Pellinen
72

Gunakan saja:

var isSafari = window.safari !== undefined;
if (isSafari) console.log("Safari, yeah!");
lukyer
sumber
15
Tidak yakin mengapa ini tidak lebih tinggi - apakah ini sempurna, pendek, dan sederhana. Saya perlu mengesampingkan safari desktop karena kurangnya getUserMedia.
Stephen Tetreault
3
ini adalah cara sempurna untuk menentukan safari desktop karena ini tidak berfungsi pada seluler
godblessstrawberry
Versi Safari apa ini berfungsi? Sepertinya tidak bekerja untuk v5.1.7
ElliotSchmelliot
Jika Anda hanya peduli dengan browser, dan bukan seluler vs desktop, ini berfungsi dengan sempurna.
Antuan
1
Ini tidak berfungsi di dalam iPhone 11 Pro Max Simulator 13.5
Christian Valentin
22

Kode ini digunakan untuk mendeteksi browser safari saja

if (navigator.userAgent.search("Safari") >= 0 && navigator.userAgent.search("Chrome") < 0) 
{
   alert("Browser is Safari");          
}
wahid
sumber
4
kode ini hanya mendeteksi apakah browser webkit bukan chrome. Banyak browser lain memiliki ide buruk untuk menyertakan "safari" dalam string agen penggunanya. Misalnya, 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)browser Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.34 Safari/534.24
Opera:,
deteksi platform melempar mungkin dapat memfilter kasus kompatibilitas tertentu.
ljgww
Saya baru saja memeriksa setengah lusin browser iOS pihak ketiga, semuanya meniru Agen Pengguna Safari yang sangat tepat.
Pertandingan Mitch
Jadi ini hanya akan mendeteksi Chrome. Namun, saya baru mengetahui bahwa Chrome 44 tidak lagi memiliki Chrome di UA, tetapi 'CriOS' sebagai gantinya :(
Mitch Match
Kami harus selalu mencoba melakukan deteksi fitur, dan menggunakan deteksi browser sebagai upaya terakhir, karena yang terakhir lebih mungkin membobol dan memblokir pengguna yang sah. Jawaban apa pun yang sama sekali tidak menyebutkan deteksi fitur mendapatkan downvote dari saya.
Flimm
13

Karena userAgent untuk chrome dan safari hampir sama, maka lebih mudah untuk melihat vendor browser

Safari

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

Chrome

navigator.vendor ==  "Google Inc."

FireFox (mengapa kosong?)

navigator.vendor ==  ""

IE (mengapa tidak ditentukan?)

navigator.vendor ==  undefined
tylerlindell.dll
sumber
1
Saya sedang mencari sesuatu untuk menonaktifkan pesan peringatan di safari di tempat kerja di berbagai komputer (desktop mac, ipads, dll), dan ini bekerja dengan sempurna.
dylnmc
Namun vendor untuk Chrome di iOS juga akan menjadi "Apple Computer, Inc.". Maaf ...
Piotr Kowalski
@PiotrKowalski - solusi apa yang Anda gunakan?
tylerlindell
@tylerlindell Lihat jawaban saya di bagian bawah halaman ini dengan kata "versi".
Piotr Kowalski
1
Ini gagal untuk versi edge berdasarkan chrome!
Qiulang
7

Hanya Safari tanpa Chrome:

Setelah mencoba kode lain, saya tidak menemukan kode yang berfungsi dengan Safari versi baru dan lama.

Akhirnya, saya melakukan kode ini yang bekerja dengan sangat baik untuk saya:

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

Saya tidak tahu mengapa OP ingin mendeteksi Safari, tetapi dalam kasus yang jarang terjadi Anda memerlukan browser sniffing saat ini, mungkin lebih penting untuk mendeteksi mesin render daripada nama browser. Misalnya di iOS, semua browser menggunakan mesin Safari / Webkit, jadi tidak ada gunanya mendapatkan "chrome" atau "firefox" sebagai nama browser jika perender yang mendasari sebenarnya Safari / Webkit. Saya belum menguji kode ini dengan browser lama tetapi berfungsi dengan semua yang cukup baru di Android, iOS, OS X, Windows dan 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>

Untuk memperjelas:

  • Semua browser di bawah iOS akan dilaporkan sebagai "safari / webkit"
  • Semua browser di bawah Android kecuali Firefox akan dilaporkan sebagai "chrome / blink"
  • Chrome, Opera, Blisk, Vivaldi dll. Semuanya akan dilaporkan sebagai "chrome / blink" pada Windows, OS X atau Linux
Christopher Martin
sumber
Versi lama IE memiliki string MSIE bukan Trident. Terkadang edge kehilangan e akhir di tepi kata. Anda harus mencari edg
PHP Guru
Ini harus menjadi jawaban baru yang diterima, terima kasih Christopher.
Myndex
5

Saya menggunakan ini

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));
}
lovepong
sumber
5

Saya mengamati bahwa hanya satu kata yang membedakan Safari - "Versi". Jadi regex ini akan bekerja dengan sempurna:

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

Jawaban paling sederhana:

function isSafari() {
 if (navigator.vendor.match(/[Aa]+pple/g).length > 0 ) 
   return true; 
 return false;
}
SudarP
sumber
3
Ini berfungsi, meskipun dapat dilakukan dengan lebih sederhana tanpa regexp:navigator.vendor.toLowerCase().indexOf('apple') > -1
fviktor
5
Bahkan lebih sederhana ... if (navigator.vendor.match(/apple/i)) { ... }.
Brad
Ini tidak berfungsi untuk iOS 13.3.1 di firefox seperti yang ditunjukkan Apple Computer, inc
chrizonline
1
@nuttynibbles: Ini mungkin yang Anda inginkan karena setiap browser di iOS adalah Safari yang menyamar.
wortwart
3

Sebagai catatan, cara teraman yang saya temukan adalah dengan mengimplementasikan bagian Safari dari kode deteksi browser dari jawaban ini :

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

Tentu saja, cara terbaik untuk menangani masalah khusus browser adalah selalu melakukan deteksi fitur, jika memungkinkan. Namun, menggunakan potongan kode seperti di atas masih lebih baik daripada deteksi string agen.

Marcos Sandrini
sumber
1
Ini tidak berfungsi dengan Safari Version / 13.1 Mobile / 15E148 Safari / 604.1 di iPhone OS 13_4_1.
mindo
2

Saya tahu pertanyaan ini sudah lama, tetapi saya tetap berpikir untuk memposting jawabannya karena dapat membantu seseorang. Solusi di atas gagal dalam beberapa kasus edge, jadi kami harus menerapkannya dengan cara yang menangani iOS, Desktop, dan platform lain secara terpisah.

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

Regex yang dimodifikasi untuk jawaban di atas

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

"Masalah" unik ini adalah 100% tanda bahwa browser itu Safari (percaya atau tidak).

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

Ini berarti deskriptor objek cookie disetel ke false di Safari sementara di sisi lain adalah benar, yang sebenarnya membuat saya pusing di proyek lain. Selamat membuat kode!

zoxxx
sumber
Sepertinya tidak lagi benar. Juga macet di Firefox "Object.getOwnPropertyDescriptor (...) undefined"
Offirmo
0

Mungkin ini berhasil:

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

EDIT: TIDAK LAGI BEKERJA

Harshal Carpenter
sumber
Apa sebenarnya yang dilakukan ini, karena return -1 di semua browser?
Petroff
@Petroff tidak lagi berfungsi di safari yang lebih baru. Terima kasih telah menunjukkannya.
Harshal Carpenter
2
Jangan ragu untuk menghapus jawabannya.
Flimm
0

Dalam kasus saya, saya perlu menargetkan Safari di iOS dan macOS. Ini berhasil untuk saya:

if (/apple/i.test(navigator.vendor)) {
  // It's Safari
}
Simone
sumber
-1

Saya membuat fungsi yang mengembalikan tipe boolean:

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

Mengendus agen pengguna benar-benar rumit dan tidak dapat diandalkan. Kami mencoba mendeteksi Safari di iOS dengan sesuatu seperti jawaban @ qingu di atas, itu bekerja dengan cukup baik untuk Safari, Chrome dan Firefox. Tapi itu salah mendeteksi Opera dan Edge sebagai Safari.

Jadi kami menggunakan fitur deteksi, seperti yang terlihat saat ini, serviceWorkerhanya didukung di Safari dan tidak di browser lain di iOS. Sebagaimana dinyatakan dalam https://jakearchibald.github.io/isserviceworkerready/

Dukungan tidak termasuk versi iOS dari browser pihak ketiga pada platform itu (lihat dukungan Safari).

Jadi kami melakukan sesuatu seperti

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

Catatan : Tidak diuji di Safari di MacOS.

AG
sumber