Обнаружение браузера

Какой лучший/самый простой/самый точный способ определить браузер пользователя?

Простота расширяемости и реализации является плюсом.

Чем меньше технологий используется, тем лучше.

Решение может быть серверным, клиентским или и тем, и другим. Однако результаты должны в конечном итоге оказаться на сервере.

Решение может быть независимым от фреймворка.

Решение будет использоваться только для целей отчетности.


person Jrgns    schedule 19.09.2008    source источник
comment
Не совсем ответ, но вы можете прочитать webaim.org/blog/ история строк агента пользователя. Если ничего другого, это действительно смешно.   -  person dsm    schedule 21.09.2008


Ответы (12)


На сервере вы в значительной степени ограничены строкой UserAgent, которую предоставляет браузер (что чревато проблемами, почитайте о история строки UserAgent).

На клиенте (т.е. в Javascript) у вас больше возможностей. Но лучший вариант — не беспокоиться о том, какой это браузер. Просто убедитесь, что функция, которую вы хотите использовать, действительно существует.

Например, вы можете использовать setCapture, который предоставляет только MSIE:

if (element.setCapture) element.setCapture()

Вместо того, чтобы выяснять, что такое браузер, а затем делать выводы о его возможностях, мы просто смотрим, поддерживает ли он что-то, прежде чем использовать его — кто знает, какие браузеры будут поддерживать что в будущем, вы действительно хотите вернуться и обновить ваши скрипты, если Safari решит поддерживать setCapture?

person Dan    schedule 19.09.2008
comment
Мне очень понравился (и я многому научился) этот пост в блоге об истории строк пользовательского агента. - person billmalarky; 20.10.2012
comment
Отличный ответ. Хотя многие по-прежнему полагаются на условные комментарии или сниффинг браузера, всегда лучше для перспективной сети, если вы просто ищете обнаружение функций. По мере развития веб-стандартов и того, что браузеры внедряют новые функции по сравнению со старыми версиями спецификаций, даже использование определенного браузера может привести к тому, что ваш веб-сайт неправильно определит, что сайт способен обрабатывать желаемые функции. Обнаружение функций — единственный способ определить, будет ли ваш сайт работать сейчас и в будущем. Спасибо, что поделились простым и точным ответом. - person tobint; 22.01.2013

плагин браузера JQuery сделает это за вас на стороне клиента.

Что такое плагин jQuery для браузера?

Плагин браузера jQuery — это надстройка для jQuery, которая позволяет легко однозначно идентифицировать браузеры ваших посетителей.

Что он делает?

Он дает вам объект в javascript, который содержит всю информацию об используемом браузере. Он также добавляет селекторы браузера CSS, что означает, что вы можете стилизовать элементы или писать функции для определенных браузеров, версий браузеров, макетов, версий макетов и даже операционных систем. Изображение подключаемого модуля браузера jQuery в действии.

Плагин делает доступным $.browser, который вы можете повторно отправить на свой сервер с помощью вызова AJAX, если он вам действительно нужен на стороне сервера.

alert($.browser.name);  // Alerts Firefox for me

Однако плагин будет настолько эффективен, насколько эффективны браузеры, с которыми он был протестирован. Перечисленный выше подключаемый модуль имеет список браузеров, распознанных в его тестах, но всегда существует риск что появится новый браузер (Google Chrome..), который потребует перезаписи правила распознавания. Тем не менее, этот плагин, похоже, регулярно обновляется.

person ConroyP    schedule 19.09.2008

При использовании JavaScript: Не использовать определение браузера.

Пишите код, который проверяет себя на заданные случаи, выставленные браузерами, иначе вы просто будете писать код для очень-очень небольшого числа пользователей. Лучше использовать "typeof foo == 'undefined'" и специфичные для браузера трюки там, где они вам нужны.

jQuery делает это по всей своей кодовой базе (если вы посмотрите на код, вы увидите, что он реализует поведение для разных технологий браузера)

Это лучше в долгосрочной перспективе.

person Kent Fredric    schedule 19.09.2008
comment
Однако, если вам нужна производительность, выполнение проверок может быть дорогостоящим. В некоторых случаях лучше знать заранее, какие методы использовать, чем проверять ошибки и менять курс каждый раз, когда вы сталкиваетесь с ними. - person Adam Davis; 20.09.2008
comment
Вопрос был не в том, почему или почему бы не использовать конкретную технику, а в том, как лучше всего реализовать выбранную им технику. Насколько вы знаете, он не хочет обнаруживать браузеры для формирования сайта, он может захотеть, чтобы он регистрировал статистику браузера. - person Captain Toad; 16.02.2012

Поскольку я только что разместил это в (теперь удаленном вопросе), и он все еще находится в моем буфере вставки, я просто опубликую. Примечание: это PHP-решение на стороне сервера.

В настоящее время я использую для этого следующий код. Это не слишком утомительное решение, но его легко реализовать в большем количестве браузеров. Я не знал о user-agents.org (спасибо PConroy), "на днях" я просмотрю его и посмотрю, смогу ли я обновить и добавить в свой список.

define("BROWSER_OPERA","Opera");
define("BROWSER_IE","IE");
define("BROWSER_OMNIWEB","Omniweb");
define("BROWSER_KONQUEROR","Konqueror");
define("BROWSER_SAFARI","Safari");
define("BROWSER_MOZILLA","Mozilla");
define("BROWSER_OTHER","other");

$aBrowsers = array
(
  array("regexp" => "@Opera(/| )([0-9].[0-9]{1,2})@", "browser" => BROWSER_OPERA, "index" => 2),
  array("regexp" => "@MSIE ([0-9].[0-9]{1,2})@", "browser" => BROWSER_IE, "index" => 1),
  array("regexp" => "@OmniWeb/([0-9].[0-9]{1,2})@", "browser" => BROWSER_OMNIWEB, "index" => 1),
  array("regexp" => "@(Konqueror/)(.*)(;)@", "browser" => BROWSER_KONQUEROR, "index" => 2),
  array("regexp" => "@Safari/([0-9]*)@", "browser" => BROWSER_SAFARI, "index" => 1),
  array("regexp" => "@Mozilla/([0-9].[0-9]{1,2})@", "browser" => BROWSER_MOZILLA, "index" => 1)
);

foreach($aBrowsers as $aBrowser)
{
  if (preg_match($aBrowser["regexp"], $_SERVER["HTTP_USER_AGENT"], $aBrowserVersion))
  {
    define("BROWSER_AGENT",$aBrowser["browser"]);
    define("BROWSER_VERSION",$aBrowserVersion[$aBrowser["index"]]);
    break;
  }
}
person Twan    schedule 19.09.2008
comment
Спасибо за репост. Удаленный вопрос, очевидно, был не очень хорошим. - person Jrgns; 19.09.2008
comment
Сам вопрос по какой-то причине получил несколько отрицательных голосов, задавший вопрос, должно быть, решил больше не рисковать своей репутацией. Может раздражать, когда вы хорошо обдумываете ответ! - person ConroyP; 19.09.2008
comment
Он начал падать, и я понял, что вопрос можно было бы лучше отформатировать, поэтому я удалил его. Извините за потерю ответов... - person Jrgns; 19.09.2008
comment
Вот почему обнаружение браузера плохо. Ваш код выше не может обнаружить Opera 10 (которая в настоящее время находится в альфа-версии). Прекрасный пример того, почему обнаружение признаков лучше. Для справки: Opera/10.00 (Windows NT 5.2; U; en) Presto/2.2.2 - person fearphage; 07.05.2009
comment
Очевидно, это легко исправить, обновив соответствующее регулярное выражение. @Opera(/| )([0-9]{1,2}.[0-9]{1,2})@ должно помочь. Обнаружение функций может устареть реже, но также требует обслуживания. Кроме того, я использую это для создания чистых файлов CSS (наряду с обнаружением функций в моих сценариях). - person Twan; 09.05.2009

как сказал Дэн: это зависит от используемой технологии.

Для обнаружения браузера на стороне сервера PHP я рекомендую обнаружение браузера Харальда Хоупа:

http://techpatterns.com/downloads/php_browser_detection.php

Опубликовано под лицензией GPL.

person Johannes Hädrich    schedule 19.09.2008

Не используйте обнаружение браузера:

  • Обнаружение браузера не на 100% надежно в лучшие времена, но дела обстоят еще хуже:
  • Существует множество вариантов браузеров (настройки MSIE и т. д.)
  • Браузеры могут лгать о своей личности (эта функция действительно встроена в Opera)
  • Шлюзы скрывают или запутывают личность браузера
  • Продавцы кастомизации и шлюза пишут свою чушь в USER_AGENT

Обнаружение признаков лучше делать в клиентском скрипте. Надеюсь, вам нужно только обнаружение браузера, чтобы обойти ошибку в конкретном браузере и версии.

person MarkR    schedule 19.09.2008
comment
Вопрос был не в том, почему или почему бы не использовать конкретную технику, а в том, как лучше всего реализовать выбранную им технику. Насколько вы знаете, он не хочет обнаруживать браузеры для формирования сайта, он может захотеть, чтобы он регистрировал статистику браузера. - person Captain Toad; 16.02.2012

Первоначально я задал этот вопрос, потому что хочу иметь возможность записывать браузеры и операционные системы, которые люди используют для доступа к моему сайту. Да, строке пользовательского агента нельзя доверять, и да, вы не должны использовать определение браузера, чтобы определить, какой код запускать в JS, но я хотел бы иметь как можно более точную статистику.

Я сделал следующее.

Я использую комбинацию JavaScript и PHP для записи статистики. JavaScript для определения браузера и ОС (поскольку это вероятно наиболее точно) и PHP для записи:

JavaScript взят из Quirksmode, PHP довольно очевиден. Я использую JS-фреймворк MooTools.

Добавьте в скрипт BrowserDetect следующее:

window.addEvent('domready', function() {
    if (BrowserDetect) {
        var q_data = 'ajax=true&browser=' + BrowserDetect.browser + '&version=' + BrowserDetect.version + '&os=' + BrowserDetect.OS;
        var query = 'record_browser.php'
        var req = new Request.JSON({url: query, onComplete: setSelectWithJSON, data: q_data}).post();
    }
});

Это определяет браузер, версию браузера и ОС браузера пользователя, и отправляет его в скрипт record_browser.php. Сценарий record_browser.php просто добавляет информацию вместе с PHP session_id и текущим user_id, если он есть.

Таблица MySQL:

CREATE TABLE `browser_detects` (
  `id` int(11) NOT NULL auto_increment,
  `session` varchar(255) NOT NULL default '',
  `user_id` int(11) NOT NULL default '0',
  `browser` varchar(255) NOT NULL default '',
  `version` varchar(255) NOT NULL default '',
  `os` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `sessionUnique` (`session`)
)

PHP-код:

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $session = session_id();
    $user_id = isset($user_id) ? $user_id ? 0;
    $browser = isset($_POST['browser']) ? $_POST['browser'] ? '';
    $version = isset($_POST['version']) ? $_POST['version'] ? '';
    $os = isset($_POST['os']) ? $_POST['os'] ? '';
    $q = $conn->prepare('INSERT INTO browser_detects (`session`, `user`, `browser`, `version`, `os`) VALUES (:session :user, :browser, :version, :os)');
    $q->execute(array(
                    ':session' => $session,
                    ':user' => $user_id,
                    ':browser' => $browser,
                    ':version' => $version,
                    ':os' => $os
                ));
}
person Jrgns    schedule 25.09.2008

Как утверждают многие, обнаружение браузера может пойти очень неправильно... однако в интересах Code Golf.

Это очень быстрый способ обнаружения IE.

<script>
  if('\v'=='v'){
    alert('I am IE');
  } else {
    alert('NOT IE');
  }
</script>

На самом деле это довольно удобно, потому что он выбирает IE, не спотыкаясь об Opera.

Бонусные баллы, если вы знаете, почему это работает в IE. ;-)

person scunliffe    schedule 14.04.2009

Это код C#, который я использую, надеюсь, будет полезен.

StringBuilder strb = new StringBuilder();
strb.AppendFormat ( "User Agent: {0}{1}", Request.ServerVariables["http_user_agent"].ToString(), Environment.NewLine );
strb.AppendFormat ( "Browser: {0}{1}", Request.Browser.Browser.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "Version: {0}{1}", Request.Browser.Version.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "Major Version: {0}{1}", Request.Browser.MajorVersion.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "Minor Version: {0}{1}", Request.Browser.MinorVersion.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "Platform: {0}{1}", Request.Browser.Platform.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "ECMA Script version: {0}{1}", Request.Browser.EcmaScriptVersion.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "Type: {0}{1}", Request.Browser.Type.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "-------------------------------------------------------------------------------{0}",  Environment.NewLine );
strb.AppendFormat ( "ActiveX Controls: {0}{1}", Request.Browser.ActiveXControls.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "Background Sounds: {0}{1}", Request.Browser.BackgroundSounds.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "AOL: {0}{1}", Request.Browser.AOL.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "Beta: {0}{1}", Request.Browser.Beta.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "CDF: {0}{1}", Request.Browser.CDF.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "ClrVersion: {0}{1}", Request.Browser.ClrVersion.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "Cookies: {0}{1}", Request.Browser.Cookies.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "Crawler: {0}{1}", Request.Browser.Crawler.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "Frames: {0}{1}", Request.Browser.Frames.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "Tables: {0}{1}", Request.Browser.Tables.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "JavaApplets: {0}{1}", Request.Browser.JavaApplets.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "JavaScript: {0}{1}", Request.Browser.JavaScript.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "MSDomVersion: {0}{1}", Request.Browser.MSDomVersion.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "TagWriter: {0}{1}", Request.Browser.TagWriter.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "VBScript: {0}{1}", Request.Browser.VBScript.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "W3CDomVersion: {0}{1}", Request.Browser.W3CDomVersion.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "Win16: {0}{1}", Request.Browser.Win16.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "Win32: {0}{1}", Request.Browser.Win32.ToString ( ), Environment.NewLine );
strb.AppendFormat ( "-------------------------------------------------------------------------------{0}", Environment.NewLine );
strb.AppendFormat ( "MachineName: {0}{1}", Environment.MachineName, Environment.NewLine );
strb.AppendFormat ( "OSVersion: {0}{1}", Environment.OSVersion, Environment.NewLine );
strb.AppendFormat ( "ProcessorCount: {0}{1}", Environment.ProcessorCount, Environment.NewLine );
strb.AppendFormat ( "UserName: {0}{1}", Environment.UserName, Environment.NewLine );
strb.AppendFormat ( "Version: {0}{1}", Environment.Version, Environment.NewLine );
strb.AppendFormat ( "UserInteractive: {0}{1}", Environment.UserInteractive, Environment.NewLine );
strb.AppendFormat ( "UserDomainName: {0}{1}", Environment.UserDomainName, Environment.NewLine );
person SoftwareARM    schedule 10.01.2011

Изменить: приведенное ниже решение не рекомендуется. Вместо этого попробуйте следующее: http://whatbrowser.net/

Когда-то это работало для меня, но, глядя на код сейчас, я понятия не имею, как это сделать. Вместо этого используйте приведенное выше :-/

<script type="text/javascript">
    // <![CDATA[
    var BrowserCheck = Class.create({
        initialize: function () {
            var userAgent = navigator.userAgent.toLowerCase();
            this.version = (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1];
            this.safari = /webkit/.test(userAgent) && !/chrome/.test(userAgent);
            this.opera = /opera/.test(userAgent);
            this.msie = /msie/.test(userAgent) && !/opera/.test(userAgent);
            this.mozilla = /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent);
            this.chrome = /chrome/.test(userAgent);
        }
    });    
    // ]]>
</script>

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

var UserBrowser = new BrowserCheck();

Затем проверьте тип и версию браузера следующим образом: (например, Internet Explorer 8)

if ((UserBrowser.msie == true) && (UserBrowser.version == 8))

и т.п.

Надеюсь, это поможет вам так же, как и нам, но помните, что никакое обнаружение браузера не является пуленепробиваемым!

person Chuck Le Butt    schedule 08.06.2010
comment
В IE9 я получаю «Класс не определен». через консоль. - person mrswadge; 04.11.2015
comment
@mrswadge Да, у меня та же проблема. Прости за это. Попробуйте вместо этого: whatbrowser.net - person Chuck Le Butt; 04.11.2015
comment
@mrswadge Кажется, используется библиотека Prototype. Я понятия не имею, почему это когда-то сработало для меня. - person Chuck Le Butt; 04.11.2015
comment
Да, я тоже это видел. Это не проблема, я проверю ссылку whatbrowser.net. Спасибо за помощь. - person mrswadge; 04.11.2015

Для Internet Explorer и таблиц стилей вы можете использовать следующий синтаксис:

<!--[if lte IE 6]><link href="/style.css" rel="stylesheet" type="text/css" /><![endif]-->

Это относится к IE 6 или более ранней версии. Вы можете изменить версию IE, а также иметь:

<!--[if eq IE 7]> = Equal too IE 7
<!--[if gt IE 6]> = Greater than IE 6

Я не уверен, работает ли это с другими частями страницы, но работает, когда помещен в тег <head>. См. этот пример для получения дополнительной информации.

person Toby Mills    schedule 19.09.2008
comment
Это был испытанный механизм для прошлых версий IE (см.: quirksmode.org/css /condcom.html). Это упразднено в пользу обнаружения функций. См. msdn.microsoft.com/en-us. /library/ms537512%28v=VS.85%29.aspx, где конкретно указано: Важно Начиная с Internet Explorer 10 условные комментарии больше не поддерживаются в стандартном режиме. Используйте обнаружение функций, чтобы обеспечить эффективные резервные стратегии для функций веб-сайта, которые не поддерживаются браузером. Дополнительные сведения о стандартном режиме см. в разделе Определение совместимости документов. - person tobint; 22.01.2013

Как правило, когда браузер делает запрос, он отправляет вам кучу информации (время, имя, дата, пользовательский агент...). Вы должны попытаться просмотреть заголовки, отправленные клиентом, и перейти к тому, который сообщает вам их браузер (я думаю, что это «User-Agent:».

person stalepretzel    schedule 25.09.2008