Обнаружить браузер Safari


142

Как обнаружить браузер Safari с помощью JavaScript? Я попробовал код ниже, и он обнаруживает не только Safari, но и браузер Chrome.

function IsSafari() {

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

}

1
Часть кода JS, относящаяся к отправке файлов, работает почтительно для Safari, для Chrome работает нормально.
— Томас

1
Вы почти наверняка должны проверять наличие различий в API. Помимо Safari и Chrome, существуют другие браузеры на основе WebKit.
— Квентин

12
Есть много причин, по которым можно захотеть обнаружить браузер. Например, на момент написания этой статьи некоторые аспекты движка SVG, такие как фильтры, не работают в Safari, но работают в Chrome.
— Пол Легато

Иногда вы просто не можете исправить ошибку, потому что вы не можете ее воспроизвести (у меня нет доступа к Mac). Я исправил проблему в Midori (некоторая проблема BlobBuilder / Blob для sendAsBinary shim), но клиент говорит, что проблема с загрузкой файлов все еще существует, поэтому лучшее, что я могу придумать, это просто удалить поддержку Safari и использовать для нее iframes (как для старый IE)
— llamerr

1
Возможный дубликат Как обнаружить браузер Chrome и
— Safari

Ответы:


110

Вы можете легко использовать индекс Chrome для фильтрации Chrome:

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

6
Не работает В настоящее время выводит хромированную строку UA на iPhone, и в ней даже нет слова "хром".
— Пол Карлтон

5
IE 11 UA строка в Windows 10 также содержит Safari и Chrome
— cuixiping

Blackberry также включает в себя «Safari».
— Гарри Пехконен

18
@Flimm Есть много законных вариантов использования для обнаружения браузером. Не позволяйте себе знать намерение спрашивающего или ответчика. Хотя полезно добавить полезный совет, который может показаться вам актуальным, это ни в коем случае не является обязательным требованием.
— Рубен Мартинес-младший

1
Это не работает в браузерах Android, включая «safari», но не «chrome»: developers.whatismybrowser.com/useragents/explore/software_name/…
— Эрик Эндрю Льюис

156

Примечание: всегда пытайтесь определить конкретное поведение, которое вы пытаетесь исправить, вместо того, чтобы указывать егоisSafari?

В крайнем случае, найдите Safari с помощью этого регулярного выражения:

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

Он использует негативные осмотры и исключает Chrome, Edge и все браузеры Android, которые включают Safariимя в свой пользовательский агент.


2
Это не работает Я все еще понимаю, если я использую браузер Chrome на iPhone.
— ayjay

27
Это потому, что все браузеры на iOS являются просто обертками для Safari (за исключением Opera Mini в режиме Mini ), включая Chrome. Это не обязательно означает, что все они будут соответствовать этому тесту, поскольку строка userAgent зависит от оболочки. Возможно, вы захотите обнаружить Chrome на iOS отдельно.
— Фреганте

Чувак, это сработало для меня !!! Спасибо огромное .. navigator.userAgent возвращал значения типа «5.0 (Windows NT 6.1) AppleWebKit / 537.36 (KHTML, как Gecko) Chrome / 39.0.2171.99 Safari / 537.36» для Chrome в Windows и Safari в Mac.
— KaustubhSV

2
Исправлено сейчас. Вы определенно правы, проблема многих браузеров заключается в том, что они включают другие имена, чтобы не остаться в стороне. Like Edge включает в себя как Chrome, так и Safari в своем UA. По этой причине проверки пользовательского агента плохие: браузеры меняются, и проверки должны быть обновлены. К сожалению, нет идеального способа обнаружить браузер, это всегда предположение.
— Фреганте

1
Это определенно хорошая идея - использовать функцию обнаружения функций, но некоторые варианты поведения сложно или почти невозможно проверить, например, отображается ли видео на мобильном устройстве автоматически в полноэкранном режиме, что происходит только на iPhone и iPod. Чтобы проверить это, вам нужно загрузить видео и попросить пользователя воспроизвести его.
— Фреганте

91

Как уже отмечали другие люди, обнаружение функции предпочтительнее, чем проверка конкретного браузера. Одна из причин заключается в том, что строка пользовательского агента может быть изменена. Другая причина в том, что строка может измениться и сломать ваш код в более новых версиях.

Если вы все еще хотите сделать это и протестировать любую версию Safari, я бы предложил использовать эту

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

Это будет работать с любой версией Safari на всех устройствах: Mac, iPhone, iPod, iPad.

редактировать

Чтобы проверить в вашем текущем браузере: https://jsfiddle.net/j5hgcbm2/

Редактировать 2

Обновлен в соответствии с документами Chrome для корректного определения Chrome на iOS

Стоит отметить, что все браузеры на iOS являются просто обертками для Safari и используют один и тот же движок. См. Комментарий bfred.it к его собственному ответу в этой теме.

Редактировать 3

Обновлен в соответствии с документацией Firefox для правильного определения Firefox на iOS


Спасибо за комментарий - Обновлено для правильного определения Chrome на iOS
— qingu

@qingu - я не понимаю этот javascript, как бы я сделал что-то вроде - если (safaribrowser) {сделать это} else {сделать это}, используя тот же код, что значение 'var isSafari' спасибо
— GAV

@GAV: isSafariбудет trueв браузере Safari, falseиначе. Вы можете просто использовать приведенный выше фрагмент, а затем использовать свой почти так, как вы его опубликовали. if (isSafari) { do_this(); } else { do_that(); },
— Qingu

2
К сожалению, есть больше причин, чтобы попытаться выяснить браузер, чем просто обнаружение функций. Браузер может поддерживать функцию, но иметь ошибки (например: ошибка холста в IE10, но та же функция работает в IE9). Кроме того, Firefox ведет себя не так, как браузеры на основе webkit, например, как он реагирует на движение мыши. В Apple Safari есть ошибки перекомпоновки, которых нет в Chrome. Некоторые браузеры также эффективны при выполнении определенных вычислительно сложных задач, чем другие.
— DemiImp

2
@Andras Для Firefox вы можете добавить && !navigator.userAgent.match('FxiOS')аналогичные проверки Chrome - ref ( developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/… )
— Петри Пеллинен,

60

Просто используйте:

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

15
Не уверен, почему это не выше - это идеально, коротко и просто. Мне нужно было исключить настольное сафари из-за отсутствия getUserMedia.
— Стивен Тетро

3
это идеальный способ определения настольного сафари, так как он не работает на мобильных устройствах
— godblessstrawberry

Для каких версий Safari это работает? Кажется, не работает для v5.1.7
— ElliotSchmelliot

Если вы заботитесь только о браузерах, а не о мобильных и настольных компьютерах, это работает отлично.
— Антуан

1
Это не сработало в iPhone 11 Pro Max Simulator 13.5
— Кристиан Валентин

19

Этот код используется для обнаружения только браузера Safari

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

4
Этот код только обнаруживает, не является ли браузер WebKit не Chrome. Многие другие браузеры имеют плохую идею включения «safari» в строку своего пользовательского агента. Например, 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)или Stock Android-браузер:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.34 Safari/534.24
— rupps

определение платформы может, возможно, отфильтровать конкретные случаи совместимости.
— августа

Я только что проверил полдюжины сторонних браузеров iOS, все они подделывают очень точный пользовательский агент Safari.
— Митч Матч

Так что это будет обнаруживать только Chrome. И все же, я только что узнал, что Chrome 44 больше не имеет Chrome в UA, а вместо этого «CriOS» :(
— Mitch Match

Мы всегда должны стараться обнаруживать функции и использовать обнаружение браузера в качестве крайней меры, так как последняя гораздо чаще ломает и блокирует законных пользователей. Любой ответ, в котором вообще не упоминается функция обнаружения, получает от меня отрицательное мнение.
— Flimm

12

Поскольку userAgent для Chrome и Safari практически одинаковы, взглянуть на поставщика браузера проще.

Сафари

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

Хром

navigator.vendor ==  "Google Inc."

FireFox (почему он пуст?)

navigator.vendor ==  ""

IE (почему он не определен?)

navigator.vendor ==  undefined

1
Я искал что-то, чтобы отключить предупреждающие сообщения в Safari при работе на разных компьютерах (рабочие столы Mac, iPad и т. Д.), И это сработало отлично.
— dylnmc

Но поставщиком для Chrome на iOS также будет «Apple Computer, Inc.». Извините ...
— Петр Ковальский

@PiotrKowalski - какое решение вы выбрали?
— Tylerlindell

@tylerlindell Смотрите мой ответ внизу этой страницы со словом "версия".
— Петр Ковальский

7

Только сафари без хрома:

Попробовав другие коды, я не нашел ни одной, которая бы работала с новыми и старыми версиями Safari.

Наконец, я сделал этот код, который очень хорошо работает для меня:

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

Я заметил, что только одно слово отличает Safari - «Версия». Так что это регулярное выражение будет работать идеально:

/.*Version.*Safari.*/.test(navigator.userAgent)

5

Я не знаю, почему ОП захотел обнаружить Safari, но в редких случаях вам нужно теперь прослушивать браузер, вероятно, гораздо важнее обнаружить механизм рендеринга, чем имя браузера. Например, в iOS все браузеры используют движок Safari / Webkit, поэтому бессмысленно указывать в качестве имени браузера «chrome» или «firefox», если в качестве базового средства визуализации используется Safari / Webkit. Я не тестировал этот код со старыми браузерами, но он работает со всем относительно недавним на Android, iOS, OS X, Windows и 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>

Чтобы уточнить:

  • Все браузеры под iOS будут отмечены как "safari / webkit"
  • Все браузеры под Android, кроме Firefox, будут отображаться как «chrome / blink»
  • Chrome, Opera, Blisk, Vivaldi и т. Д. Будут сообщаться как «chrome / blink» в Windows, OS X или Linux

4

Я использую это

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

4

Самый простой ответ:

function isSafari() {
 if (navigator.vendor.match(/[Aa]+pple/g).length > 0 ) 
   return true; 
 return false;
}

2
Это работает, хотя можно было бы сделать проще без регулярных выражений:navigator.vendor.toLowerCase().indexOf('apple') > -1
— fviktor

5
Еще проще ... if (navigator.vendor.match(/apple/i)) { ... }.
— Брэд

Это не работает для ios 13.3.1 на firefox, поскольку показывает Apple Computer, inc
— nuttynibbles

1
@nuttynibbles: Это, вероятно, то, что вы хотите, потому что каждый браузер на iOS является замаскированным Safari.
— пустырник

3

Для записей самый безопасный способ, который я нашел, это реализовать часть Safari кода обнаружения браузера из этого ответа :

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

Конечно, лучшим способом решения проблем, связанных с браузером, всегда является обнаружение функций, если это вообще возможно. Однако использование кода, подобного приведенному выше, все же лучше, чем определение строки агента.


1
Это не работает с Safari Version / 13.1 Mobile / 15E148 Safari / 604.1 на iPhone OS 13_4_1.
— Миндо

2

Я знаю, что этот вопрос старый, но я все равно решил опубликовать ответ, так как он может кому-то помочь. В некоторых крайних случаях вышеприведенные решения не дали результата, поэтому нам пришлось реализовать его таким образом, чтобы обрабатывать iOS, Desktop и другие платформы отдельно.

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

Модифицированный регулярное выражение для ответа выше

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

1

Эта уникальная «проблема» является 100% признаком того, что браузер Safari (верите или нет).

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

Это означает, что дескриптор объекта cookie установлен в false в Safari, а для всех остальных - true, что фактически вызывает головную боль в другом проекте. Удачного кодирования!


Кажется, больше не правда. Также происходит сбой в Firefox «Object.getOwnPropertyDescriptor (...) не определен»
— Offirmo

0

Может быть, это работает:

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

РЕДАКТИРОВАТЬ: НЕ Дольше работать


Что именно это делает, потому что возвращает -1 во всех браузерах?
— Petroff

@Petroff больше не работает в новом сафари. Спасибо за указание на это.
— Харшал Карпентер

2
Не стесняйтесь удалить ответ.
— Flimm

0

Я создаю функцию, которая возвращает логический тип:

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

-2

Нюхание агента пользователя действительно сложно и ненадежно. Мы пытались обнаружить Safari на iOS с помощью чего-то вроде ответа @ qingu выше, он работал довольно хорошо для Safari, Chrome и Firefox. Но он ошибочно определил Opera и Edge как Safari.

Итак, мы пошли с обнаружением функций, как это выглядит на сегодняшний день, serviceWorkerподдерживается только в Safari, а не в любом другом браузере на iOS. Как указано в https://jakearchibald.github.io/isserviceworkerready/

Поддержка не включает версии iOS сторонних браузеров на этой платформе (см. Поддержку Safari).

Итак, мы сделали что-то вроде

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

Примечание : не тестировалось в Safari на MacOS.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.