Javascript.RU

Функция определения браузера и его версии

Как-то потребовалось создать функцию, принимающую объект json со следующим форматом записи: "браузер":то, что следует вернуть, иначе говоря такую функцию, которая бы возвращала указанный объект в зависимости от браузера пользователя.

ТЗ, которое я для себя определил:

  • браузеры можно группировать, указывая их через пробел
  • браузерам можно задавать версию (ie6,opera10)
  • браузерам можно задавать полную версию (opera10.15)
  • поддержка самых популярных браузеров

Мой способ гарантированно не самый точный, так как он используют свойство userAgent объекта navigator, которое при желании подделывается, но с другой стороны любой способ проверки клиента как серверный, так и клиентский можно обойти. Так же встает вопрос о надобности такой "подделки", тем более мало какие роботы исполняют javascript код.

После изучения следующей статьи http://ru.wikipedia.org/wiki/Useragent, я написал функцию ifBrowser. Она поддерживает проверку следующий браузеров: Internet Explorer, Firefox, Opera, Chrome, Safari, Konqueror, Iceweasel, SeaMonkey.

Код функции:

/*
	ifBrowser 0.0.3
	a function which returns specified data depending on a user's browser
	written by Plyushch Gregory, 2012
	is free to use for everyone in condition of saving the author's name
*/
function ifBrowser (obj) {
	var none = obj["none"] || "none";
	function cBrowser() {
		var ua = navigator.userAgent;
		var bName = function () {
			if (ua.search(/MSIE/) > -1) return "ie";
			if (ua.search(/Firefox/) > -1) return "firefox";
			if (ua.search(/Opera/) > -1) return "opera";
			if (ua.search(/Chrome/) > -1) return "chrome";
			if (ua.search(/Safari/) > -1) return "safari";
			if (ua.search(/Konqueror/) > -1) return "konqueror";
			if (ua.search(/Iceweasel/) > -1) return "iceweasel";
			if (ua.search(/SeaMonkey/) > -1) return "seamonkey";}();
		var version = function (bName) {
			switch (bName) {
				case "ie" : return (ua.split("MSIE ")[1]).split(";")[0];break;
				case "firefox" : return ua.split("Firefox/")[1];break;
				case "opera" : return ua.split("Version/")[1];break;
				case "chrome" : return (ua.split("Chrome/")[1]).split(" ")[0];break;
				case "safari" : return (ua.split("Version/")[1]).split(" ")[0];break;
				case "konqueror" : return (ua.split("KHTML/")[1]).split(" ")[0];break;
				case "iceweasel" : return (ua.split("Iceweasel/")[1]).split(" ")[0];break;
				case "seamonkey" : return ua.split("SeaMonkey/")[1];break;
			}}(bName);
		return [bName,bName + version.split(".")[0],bName + version];
	}
	var current_browser = cBrowser();
	for (var key in obj) {
		var trg = key.toLowerCase();
		if (trg.indexOf(current_browser[2]) > -1) return obj[key];
		else if (trg.indexOf(current_browser[1]) > -1) return obj[key];
		else {
			var nsymbol = trg.charAt(trg.indexOf(current_browser[0])+current_browser[0].length);
			if (trg.indexOf(current_browser[0]) > -1 && (nsymbol == " " || nsymbol == "")) return obj[key];
		};
	}
	return none;
}

http://gregivy.tf9.ru/ivyco/ifbrowser.js

В случае если ни одного выражение не совпадает с браузером пользователя, возвращается "none", которое можно также указать как свойство передаваемого объекта.

Пример использования: (данный код повернет на 25 градусов все содержимое страницы в любом современном браузере)

var transform = ifBrowser({
	"ie":"msTransform",
	"chrome safari":"WebkitTransform",
	"firefox":"MozTransform",
	"opera":"OTransform",
					
}) // определяем название нужного нам css свойства
document.body.style[transform] = "rotate(25deg)"

Пример наклона картинки на 60 градусов

Название браузера нужно вводить в следующем формате : ie, firefox, opera, chrome, safari, konqueror, iceweasel, seamonkey. Регистр неважен. Версия пишется слитно с название, пример: ie7. Если для нескольких браузеров должно возвратиться одно и тоже значение, вы просто указываете их через пробел, как
на примере ("chrome safari":"WebkitTransform"). В качестве возвращаемого значения может выступать любой объект JavaScript (строка, число, функция, логическое значение и т.д.)

+1

Автор: mihdan, дата: 1 августа, 2012 - 14:41
#permalink

Зачем проверять версию браузера и юзерагент, когда надо проверять то, что он умеет. Тем более, что ваш код даст огромную погрешность. Да и многие браузеры неправильно отдают свой агент.


Автор: Плющ Григорий, дата: 1 августа, 2012 - 23:58
#permalink

Я перечислил какие браузеры поддерживаются, они не будут "неправильно" отдавать свой юзер-агент. И версия для каждого браузера определяется по индивидуальному правилу. Мне так же интересно, как вы будете проверять то, что умеет браузер, с большей пользой, когда любое свойство можно подменить, как и юзер-агент.


Автор: torbasow, дата: 5 августа, 2012 - 14:38
#permalink

Это они на текущий момент не будут неправильно отдавать юзер-агент. Но никто не может поручиться за то, что будет завтра.
Конечно, проверять надо поддержку браузером конкретных свойств и методов. Путаница в юзер-агентах — правило, а неправильное определение стандартных свойств и методов — редкое исключение и косяк.


Автор: kvmutl, дата: 26 августа, 2012 - 10:21
#permalink

юзерагент без затей меняется, например в фаерфоксе без всяких бубнов, в системных параметрах браузера. к сожалению предложенный вами способ ненадежен и необъективен


Автор: Плющ Григорий, дата: 26 августа, 2012 - 12:52
#permalink

И что?) Кому это нужно?) С таким же успехом можно подделать любое свойство в javascript'е. Например, только в google chrome у объекта window есть свойство chrome, и многие именно так определяют браузер (вообще не важно какое свойство подменять, я просто привел пример). Подменяем: window.chrome = {}. Теперь программа будет думать, что пользователь использует гугл хром. Вот только все равно не понятно, зачем пользователю это нужно. Если пользователь достаточно грамотный, и меняет юзер агент браузера, то он соответственно понимает, что делает) Вы же не сможете защить свой сайт от того, что какой-то пользователь решил подключить к браузеру плагин удаляющей определенный контент со страницы, или от того, что пользователь пару dom-элементов удалил через консоль того же хрома.


Автор: Гость (не зарегистрирован), дата: 9 октября, 2012 - 21:00
#permalink

В Opera он тоже легко подменяется в параметре Custom User Agent в opera:config. Там же меняется и navigator.appName.


Автор: Гость (не зарегистрирован), дата: 26 октября, 2013 - 12:35
#permalink

судя по скрипту, он ищет непонятно где, не ясно что. где сам источник версии браузера, откуда берутся аргументы?


Автор: I_CaR, дата: 6 мая, 2014 - 04:45
#permalink

Спасибо! Везде работает кроме IE!!! :D (ie 6-ка)
IE Стабилен, как всегда


Автор: Гость (не зарегистрирован), дата: 22 июля, 2014 - 18:53
#permalink

Спасибо за понятный и прозрачный код.


Автор: triline (не зарегистрирован), дата: 5 ноября, 2014 - 14:26
#permalink

Не понимаю зачем было разводить флейм на тему ненадежности метода. 90% пользователей вообще не знают про строку юзерагента, а те, кто знают, изменяя эту строку, сами себе становятся злобными буратинами.

Автору зачет, респект и уважуха.


Автор: Гость (не зарегистрирован), дата: 28 июля, 2015 - 14:21
#permalink

Все течет, все меняется - в IE10 данная функция работать не будет, потому что она ищет в userAgent подстроку "MSIE", а десятый ослик userAgent отдает вот такой: "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; rv:11.0) like Gecko". Т.е. надо добавить поиск по названию IE-шного движка - Trident.


Автор: Roman Yakovlev (не зарегистрирован), дата: 25 октября, 2015 - 01:07
#permalink

Спс большое за мануал!


Автор: Гость (не зарегистрирован), дата: 19 февраля, 2016 - 08:18
#permalink

вах вах вах. в IE10 зер гуд как работает у меня. Вот в IE11 не работает. Пришлось немного отсебятины сделать.

function ifBrowser(obj) {
	var none = obj["none"] || "none";
	function cBrowser() {
		var ua = navigator.userAgent;
		var bName = function () {
			if (ua.search(/MSIE/) > -1) return "ie";
			if (ua.search(/Trident/) > -1) return "iet";
			if (ua.search(/Firefox/) > -1) return "firefox";
			if (ua.search(/Opera/) > -1) return "opera";
			if (ua.search(/Chrome/) > -1) return "chrome";
			if (ua.search(/Safari/) > -1) return "safari";
			if (ua.search(/Konqueror/) > -1) return "konqueror";
			if (ua.search(/Iceweasel/) > -1) return "iceweasel";
			if (ua.search(/SeaMonkey/) > -1) return "seamonkey";
		}();
		var version = function (bName) {
			switch (bName) {
				case "iet": return (ua.split("Trident/")[1]).split(";")[0]; break;
				case "ie": return (ua.split("MSIE ")[1]).split(";")[0]; break;
				case "firefox": return ua.split("Firefox/")[1]; break;
				case "opera": return ua.split("Version/")[1]; break;
				case "chrome": return (ua.split("Chrome/")[1]).split(" ")[0]; break;
				case "safari": return (ua.split("Version/")[1]).split(" ")[0]; break;
				case "konqueror": return (ua.split("KHTML/")[1]).split(" ")[0]; break;
				case "iceweasel": return (ua.split("Iceweasel/")[1]).split(" ")[0]; break;
				case "seamonkey": return ua.split("SeaMonkey/")[1]; break;
			}
		}(bName);
		return [bName, bName + version.split(".")[0], bName + version];
	}
	var current_browser = cBrowser();
	for (var key in obj) {
		var trg = key.toLowerCase();
		if (trg.indexOf(current_browser[2]) > -1) return obj[key];
		else if (trg.indexOf(current_browser[1]) > -1) return obj[key];
		else {
			var nsymbol = trg.charAt(trg.indexOf(current_browser[0]) + current_browser[0].length);
			if (trg.indexOf(current_browser[0]) > -1 && (nsymbol == " " || nsymbol == "")) return obj[key];
		};
	}
	return none;
}

var action = ifBrowser({
	"ie8": "action",
	"ie9": "action",
	"ie10": "action",
	"iet": "action"
});

Автор: Guest (не зарегистрирован), дата: 6 марта, 2016 - 17:37
#permalink

Author thank you very much!


Автор: viruseg (не зарегистрирован), дата: 18 марта, 2016 - 10:54
#permalink

Вот, переделал под современные реалии и улучшил юзабилити:

function getBrowser() {
    var ua = navigator.userAgent;

    var bName = function () {
        if (ua.search(/Edge/) > -1) return "edge";
        if (ua.search(/MSIE/) > -1) return "ie";
        if (ua.search(/Trident/) > -1) return "ie11";
        if (ua.search(/Firefox/) > -1) return "firefox";
        if (ua.search(/Opera/) > -1) return "opera";
        if (ua.search(/OPR/) > -1) return "operaWebkit";
        if (ua.search(/YaBrowser/) > -1) return "yabrowser";
        if (ua.search(/Chrome/) > -1) return "chrome";
        if (ua.search(/Safari/) > -1) return "safari";
        if (ua.search(/Maxthon/) > -1) return "maxthon";
    }();

    var version;
    switch (bName) {
        case "edge":
            version = (ua.split("Edge")[1]).split("/")[1];
            break;
        case "ie":
            version = (ua.split("MSIE ")[1]).split(";")[0];
            break;
        case "ie11":
            bName = "ie";
            version = (ua.split("; rv:")[1]).split(")")[0];
            break;
        case "firefox":
            version = ua.split("Firefox/")[1];
            break;
        case "opera":
            version = ua.split("Version/")[1];
            break;
        case "operaWebkit":
            bName = "opera";
            version = ua.split("OPR/")[1];
            break;
        case "yabrowser":
            version = (ua.split("YaBrowser/")[1]).split(" ")[0];
            break;
        case "chrome":
            version = (ua.split("Chrome/")[1]).split(" ")[0];
            break;
        case "safari":
            version = (ua.split("Version/")[1]).split(" ")[0];
            break;
        case "maxthon":
            version = ua.split("Maxthon/")[1];
            break;
    }

    var platform = 'desktop';
    if (/iphone|ipad|ipod|android|blackberry|mini|windows\sce|palm/i.test(navigator.userAgent.toLowerCase())) platform = 'mobile';

    var browsrObj;

    try {
        browsrObj = {
            platform: platform,
            browser: bName,
            versionFull: version,
            versionShort: version.split(".")[0]
        };
    } catch (err) {
        browsrObj = {
            platform: platform,
            browser: 'unknown',
            versionFull: 'unknown',
            versionShort: 'unknown'
        };
    }

    return browsrObj;
}

Результат выполнения функции:

Object {
platform: "desktop", 
browser: "chrome", 
versionFull: "51.0.2681.1", 
versionShort: "51"
}

Определение мобильных браузеров не поддерживается, но для них возвращается platform: "mobie".

Konqueror, Iceweasel, SeaMonkey выкинул за ненадобностью. Кому нужно их определять в 2016 году даже представить не могу.


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
1 + 7 =
Введите результат. Например, для 1+3, введите 4.
 
Поиск по сайту
Другие записи этого автора
Больше записей нет. Прокомментируйте эту запись - может быть, тогда он что-нибудь еще хорошее напишет ;)
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Популярные таги
Последние комментарии
Последние темы на форуме
Forum