我需要从用户代理字符串中提取操作系统的名称和浏览器的名称。
用户代理示例:
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.9) Gecko/20100825 Ubuntu/9.10 (karmic) Firefox/3.6.9
如何才能获得操作系统(示例"Linux i686"
和"Firefox 3.6.9"
)?
以下是我的小提琴link中的代码,如下所示:
function getBrowserAndOS(userAgent, elements) {
var browserList = {
'Chrome': [/Chrome\/(\S+)/],
'Firefox': [/Firefox\/(\S+)/],
'MSIE': [/MSIE (\S+);/],
'Opera': [
/Opera\/.*?Version\/(\S+)/,
/Opera\/(\S+)/
],
'Safari': [/Version\/(\S+).*?Safari\//]
},
re, m, browser, version;
var osList = {
'Windows': [/Windows\/(\S+)/],
'Linux': [/Linux\/(\S+)/]
},
re2, m2, os;
if (userAgent === undefined)
userAgent = navigator.userAgent;
if (elements === undefined)
elements = 2;
else if (elements === 0)
elements = 1337;
for (browser in browserList) {
while (re = browserList[browser].shift()) {
if (m = userAgent.match(re)) {
version = (m[1].match(new RegExp('[^.]+(?:\.[^.]+){0,' + --elements + '}')))[0];
//version = (m[1].match(new RegExp('[^.]+(?:\.[^.]+){0,}')))[0];
//return browser + ' ' + version;
console.log(browser + ' ' + version);
}
}
}
for (os in osList) {
while (re2 = osList[os].shift()) {
if (m2 = userAgent.match(re2)) {
//version = (m[1].match(new RegExp('[^.]+(?:\.[^.]+){0,' + --elements + '}')))[0];
//version = (m[1].match(new RegExp('[^.]+(?:\.[^.]+){0,}')))[0];
//return browser + ' ' + version;
console.log(os);
}
}
}
return null;
}
console.log(getBrowserAndOS(navigator.userAgent, 2));
我只需要提取操作系统名称和浏览器名称及其各自的版本。如何解析它以获得那些字符串?
答案 0 :(得分:1)
您是否计划根据用户代理(UA)字符串中的“嗅探”浏览器控制您网站的行为?
请不要;改为使用特征检测。
实施不当(非未来)用户代理嗅探已被证明是每次新版Internet Explorer发布时遇到的最大兼容性问题。因此,多年来围绕用户代理字符串的逻辑变得越来越复杂;兼容模式的引入意味着浏览器现在有多个UA字符串,并且在多年滥用后,该字符串的遗留可扩展性已被弃用。
默认情况下,Windows 8.1上的Internet Explorer 11发送以下用户代理字符串:
Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko
这个字符串是故意设计的,可以使大多数UA字符串嗅探逻辑将其解释为Gecko或WebKit。这个设计选择非常谨慎 - IE团队测试了许多UA字符串变体,以找出哪些会导致大多数网站为IE11用户“正常工作”。
以下two links实际上会对您有所帮助。您可能还想查看我的大部分评论的original source。
答案 1 :(得分:1)
这是用于识别操作系统的本机JavaScript解决方案,但无论何时引入新操作系统,都需要手动更新:
function getOs (userAgent) {
//Converts the user-agent to a lower case string
var userAgent = userAgent.toLowerCase();
//Fallback in case the operating system can't be identified
var os = "Unknown OS Platform";
//Corresponding arrays of user-agent strings and operating systems
match = ["windows nt 10","windows nt 6.3","windows nt 6.2","windows nt 6.1","windows nt 6.0","windows nt 5.2","windows nt 5.1","windows xp","windows nt 5.0","windows me","win98","win95","win16","macintosh","mac os x","mac_powerpc","android","linux","ubuntu","iphone","ipod","ipad","blackberry","webos"];
result = ["Windows 10","Windows 8.1","Windows 8","Windows 7","Windows Vista","Windows Server 2003/XP x64","Windows XP","Windows XP","Windows 2000","Windows ME","Windows 98","Windows 95","Windows 3.11","Mac OS X","Mac OS X","Mac OS 9","Android","Linux","Ubuntu","iPhone","iPod","iPad","BlackBerry","Mobile"];
//For each item in match array
for (var i = 0; i < match.length; i++) {
//If the string is contained within the user-agent then set the os
if (userAgent.indexOf(match[i]) !== -1) {
os = result[i];
break;
}
}
//Return the determined os
return os;
}
答案 2 :(得分:0)
我不建议你自己这样做。我使用像Platform.js这样的解析器,其工作原理如下:
<script src="platform.js"></script>
<script>
var os = platform.os;
var browser = platform.name + ' ' + platform.version;
</script>
答案 3 :(得分:0)
Useragent不是一组用于询问诸如“你是什么?”之类的定性问题的元数据,它们实际上仅对诸如“你是Linux吗?”或“ Firefox的哪个版本”之类的是/否问题有用。是吗?”。
让我说明一下,这是一个将用户代理转换成可爱的json可序列化对象的脚本:
parseUA = (() => {
//useragent strings are just a set of phrases each optionally followed by a set of properties encapsulated in paretheses
const part = /\s*([^\s/]+)(\/(\S+)|)(\s+\(([^)]+)\)|)/g;
//these properties are delimited by semicolons
const delim = /;\s*/;
//the properties may be simple key-value pairs if;
const single = [
//it is a single comma separation,
/^([^,]+),\s*([^,]+)$/,
//it is a single space separation,
/^(\S+)\s+(\S+)$/,
//it is a single colon separation,
/^([^:]+):([^:]+)$/,
//it is a single slash separation
/^([^/]+)\/([^/]+)$/,
//or is a special string
/^(.NET CLR|Windows)\s+(.+)$/
];
//otherwise it is unparsable because everyone does it differently, looking at you iPhone
const many = / +/;
//oh yeah, bots like to use links
const link = /^\+(.+)$/;
const inner = (properties, property) => {
let tmp;
if (tmp = property.match(link)) {
properties.link = tmp[1];
}
else if (tmp = single.reduce((match, regex) => (match || property.match(regex)), null)) {
properties[tmp[1]] = tmp[2];
}
else if (many.test(property)) {
if (!properties.properties)
properties.properties = [];
properties.properties.push(property);
}
else {
properties[property] = true;
}
return properties;
};
return (input) => {
const output = {};
for (let match; match = part.exec(input); '') {
output[match[1]] = {
...(match[5] && match[5].split(delim).reduce(inner, {})),
...(match[3] && {version:match[3]})
};
}
return output;
};
})();
//parseUA('user agent string here');
使用此方法,我们可以转换出以下用户代理:
`Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E)`
{
"Mozilla": {
"compatible": true,
"MSIE": "7.0",
"Windows": "NT 6.0",
"WOW64": true,
"Trident": "4.0",
"SLCC1": true,
".NET CLR": "3.0.30729",
".NET4.0C": true,
".NET4.0E": true,
"version": "4.0"
}
}
`Mozilla/5.0 (SAMSUNG; SAMSUNG-GT-S8500-BOUYGUES/S8500AGJF1; U; Bada/1.0; fr-fr) AppleWebKit/533.1 (KHTML, like Gecko) Dolfin/2.0 Mobile WVGA SMM-MMS/1.2.0 NexPlayer/3.0 profile/MIDP-2.1 configuration/CLDC-1.1 OPN-B`
{
"Mozilla": {
"SAMSUNG": true,
"SAMSUNG-GT-S8500-BOUYGUES": "S8500AGJF1",
"U": true,
"Bada": "1.0",
"fr-fr": true,
"version": "5.0"
},
"AppleWebKit": {
"KHTML": "like Gecko",
"version": "533.1"
},
"Dolfin": {
"version": "2.0"
},
"Mobile": {},
"WVGA": {},
"SMM-MMS": {
"version": "1.2.0"
},
"NexPlayer": {
"version": "3.0"
},
"profile": {
"version": "MIDP-2.1"
},
"configuration": {
"version": "CLDC-1.1"
},
"OPN-B": {}
}
`Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Comodo_Dragon/4.1.1.11 Chrome/4.1.249.1042 Safari/532.5`
{
"Mozilla": {
"Windows": "NT 5.1",
"U": true,
"en-US": true,
"version": "5.0"
},
"AppleWebKit": {
"KHTML": "like Gecko",
"version": "532.5"
},
"Comodo_Dragon": {
"version": "4.1.1.11"
},
"Chrome": {
"version": "4.1.249.1042"
},
"Safari": {
"version": "532.5"
}
}
`Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36`
{
"Mozilla": {
"X11": true,
"Fedora": true,
"Linux": "x86_64",
"version": "5.0"
},
"AppleWebKit": {
"KHTML": "like Gecko",
"version": "537.36"
},
"Chrome": {
"version": "73.0.3683.86"
},
"Safari": {
"version": "537.36"
}
}
`Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0`
{
"Mozilla": {
"X11": true,
"Fedora": true,
"Linux": "x86_64",
"rv": "66.0",
"version": "5.0"
},
"Gecko": {
"version": "20100101"
},
"Firefox": {
"version": "66.0"
}
}
`Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36`
{
"Mozilla": {
"X11": true,
"Linux": "x86_64",
"version": "5.0"
},
"AppleWebKit": {
"KHTML": "like Gecko",
"version": "537.36"
},
"Chrome": {
"version": "73.0.3683.103"
},
"Safari": {
"version": "537.36"
}
}
`Mozilla/5.0 (Linux; Android 6.0.1; SM-G920V Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.98 Mobile Safari/537.36`
{
"Mozilla": {
"Linux": true,
"Android": "6.0.1",
"SM-G920V": "Build/MMB29K",
"version": "5.0"
},
"AppleWebKit": {
"KHTML": "like Gecko",
"version": "537.36"
},
"Chrome": {
"version": "52.0.2743.98"
},
"Mobile": {},
"Safari": {
"version": "537.36"
}
}
`Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1 (compatible; AdsBot-Google-Mobile; +http://www.google.com/mobile/adsbot.html)`
{
"Mozilla": {
"iPhone": true,
"properties": [
"CPU iPhone OS 9_1 like Mac OS X"
],
"version": "5.0"
},
"AppleWebKit": {
"KHTML": "like Gecko",
"version": "601.1.46"
},
"Version": {
"version": "9.0"
},
"Mobile": {
"version": "13B143"
},
"Safari": {
"compatible": true,
"AdsBot-Google-Mobile": true,
"link": "http://www.google.com/mobile/adsbot.html",
"version": "601.1"
}
}
如果您将扩展为人类,那么您可以轻松地读取以下操作系统版本:Mozilla.Windows = NT 6.0
,Mozilla.Bada = 1.0
,Mozilla.Fedora && Mozilla.Linux = x86_64
。
但是您看到问题了吗?他们都没有说OS = "Windows"
,OS = "Samsung Bada"
等。
要问您想要的问题,您需要对所有可能的值有所了解,就像上面@Peter Wetherall
所尝试的那样,或者说“我只在乎这些少数的浏览器/操作系统”,例如您有什么问题。
如果可以,并且您不是要使用信息来更改代码的工作方式(按照@Sophit
不应这样做),而只是想显示有关浏览器的内容,我会使用上面的parseUA()
与手动检查Mozilla.Windows || Mozilla.Linux || //et cetera
的组合,与尝试通过正则表达式对原始useragent字符串进行幸运操作相比,这种方法更容易出错(这会导致误报:请参见浏览器Comodo_Dragon说:“ Chrome”)。