使用Javascript检测Chrome OS

5

我希望用Javascript检测Chrome OS,我使用navigator.userAgent来实现。现在,我正在运行Chrome OS,我的navigator userAgent是:

Mozilla/5.0 (X11; CrOS armv7l 6680.78.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.102 Safari/537.36

现在,我使用正则表达式来检查userAgent的样式,并编写了以下代码。
<script>
    if ( navigator.userAgent = /^Mozilla\/\d{1}^.\d{1}^(X11; CrOS i\d{3} \d{1}^.\d{2}\d{3} ^AppleWebKit\/\d{3}^.\d{2} ^(KHTML, like Gecko) Chrome\/ \d{2}^.\d{1}^.\d{3}^.\d{2} ^Safari\/\d{3}^\d{2}/ ){
      console.log(navigator.userAgent);
    } else {
      console.log(navigator.userAgent);
    }
</script>

现在,加载这个脚本时,我遇到了一个错误。
Uncaught SyntaxError: Invalid regular expression: /^Mozilla\/\d{1}^.\d{1}^(X11; CrOS i\d{3} \d{1}^.\d{2}\d{3} ^AppleWebKit\/\d{3}^.\d{2} ^(KHTML, like Gecko) Chrome\/ \d{2}^.\d{1}^.\d{3}^.\d{2} ^Safari\/\d{3}^\d{2}/: Unterminated group

这里我的代码有什么问题吗?

3
在编写更多查看用户代理的代码之前,您可能希望考虑改用特征检测。当然,如果您描述了尝试使用Chrome OS解决的实际问题,我们当然可以帮助您进行特征检测。 - jfriend00
@jfriend00 感谢您的建议,使用特性检测,我肯定会在以后使用那个链接,但对于这个Web应用程序,我宁愿查看用户代理。 - FoxInFlame
你为什么认为用户代理检测更好? - jfriend00
@jfriend00 我是这么认为的,因为Chrome OS本质上只是Chrome浏览器。我想要检测操作系统,而不是浏览器类型。如果我错了,请纠正我。 - FoxInFlame
1
除非您告诉我们为什么要检测Chrome OS(例如这里的真正问题是什么),否则我们无法就使用功能检测进行有意义的对话。您正在询问您选择的特定解决方案,而不是告诉我们您试图解决的真正问题,这是人们在SO上限制自己的常见方式。 - jfriend00
@jfriend00 专有应用程序。也许他正在尝试打造下一个谷歌。你想要一份吗?这个问题对我很有用..... - jeffbRTC
3个回答

13
它抱怨的是你有一个没有匹配的")"括号。在正则表达式中,"("和")"定义了捕获组并且必须保持平衡。如果你想匹配实际的"("或")",你需要用反斜杠进行转义。
但是还有其他几个问题。例如,在表达式中除了开头以外的任何地方都不应该出现"^"(表示输入的开头)。
但我认为没有别的东西会在用户代理中放置"CrOS",所以或许可以简单地:
if (/\bCrOS\b/.test(navigator.userAgent)) {
    // yes, it is (probably, if no one's mucked about with their user agent string)
} else {
    // No, it isn't (probably, if no one's mucked about with their user agent string)
}
\b是“单词边界”,因此我们不会匹配单词中间的字符串。注意,我将它保留为区分大小写。
附注:我发现https://regex101.com/#javascript(与我无关)非常有用,可以用于调试正则表达式。
附注2:如果您真的需要检测ChromeOS,则上述内容很有用,但是如果只是需要检查一个特定功能,如jfriend00指出,那么功能检测可能更好些。

感谢您对我的问题进行了详细的解答,并提供了我从未见过的链接。这次我将更倾向于使用用户代理而不是特性检测。 - FoxInFlame

7
这个怎么样?
var chromeOS = /(CrOS)/.test(navigator.userAgent);

因为Chrome OS用户代理看起来像这样:

Mozilla/5.0 (X11; CrOS i686 0.12.433) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.77 Safari/534.30

过滤掉“CrOS”是一个很好的解决方案。

1
"g"代表什么,它在你的例子中有什么用途? - FoxInFlame
这是一个全局修饰符,可以找到所有匹配项而不仅仅是第一个。但我想在这里可以将其删除,参见我的编辑答案。 - bytecode77
1
如果你要使用.test,那么使用捕获组也没有任何意义。 - T.J. Crowder

4

我用这个:

这很简单,你可以避免使用正则表达式。如果你想要的话,可以增加更多代理。

// Detect if the OS is Windows or Chrome OS

var detectedOS;

if (window.navigator.userAgent.indexOf("Windows") != -1) {detectedOS = "Windows";}
if (window.navigator.userAgent.indexOf("CrOS") != -1) {detectedOS = "Chrome";}

alert("detectedOS: " + detectedOS);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接