Browser detection using the user agent
向不同的浏览器提供不同的网页或服务通常是一个坏主意。无论用户使用哪种浏览器或设备,Web都应该可供所有人访问。有很多方法可以根据功能的可用性而不是针对特定的浏览器来开发自己的网站以逐步提升自身。
但浏览器和标准并不完美,并且仍然存在一些需要检测浏览器的边缘情况。使用用户代理来检测浏览器看起来很简单,但做得很好实际上是一个非常困难的问题。本文件将指导您尽可能正确地做到这一点。
这值得重新思考:使用用户代理嗅探非常不好。您几乎总能找到更好,更广泛兼容的方式来解决您的问题!
使用浏览器检测前的注意事项
当考虑使用用户代理字符串来检测正在使用的浏览器时,如果可能的话,您的第一步是尽量避免它。首先尝试确定你为什么要这样做。
你是否试图在某个版本的浏览器中解决特定的错误?在专门的论坛中查看或询问:你不可能成为第一个遇到这个问题的人。另外,专家或者仅仅是拥有另一种观点的人,可以为您提供解决错误的方法。如果这个问题看起来并不常见,那么值得检查这个bug是否已经通过他们的bug跟踪系统(Mozilla ; WebKit ; Opera)。浏览器制造商确实注意到错误报告,分析可能会暗示其他错误的解决方法。您是否试图检查是否存在特定功能?您的网站需要使用某些浏览器不具备的特定Web功能,还没有支持,你想发送这些用户到一个功能较少的旧网站,但你知道会工作。这是使用用户代理检测的最坏原因,因为最终所有其他浏览器都会迎头赶上。你应该尽量避免在这种情况下使用用户代理嗅探,而是做功能检测。是否要根据使用哪种浏览器提供不同的HTML?这通常是一种不好的做法,但在某些情况下这是必要的。在这些情况下,你应该首先分析你的情况,确保它确实是必要的。<div>
或<span>
元素?成功使用用户代理检测的困难值得对HTML的纯度造成一些干扰。此外,重新考虑您的设计:您可以使用渐进增强或流体布局来帮助消除这种需求吗?
避免用户代理检测
如果您想尽量避免使用用户代理检测,则在某些情况下有选项!
功能检测功能检测是您不试图找出哪个浏览器正在呈现您的页面的位置,而是检查您需要的特定功能是否可用。如果不是,则使用后备。但是,在极少数情况下,如果实际上需要浏览器检测,请不要使用功能检测,因为其他浏览器将来可能会实现此功能,但方式不同。由此造成的错误可能难以找到并修复。进度增强此设计技术涉及使用自下而上的方法在“图层”中开发您的网站,从更简单的图层开始,并在连续图层中提高网站的功能,每个使用更多features.Graceful降级这是一种自上而下的方法,您可以使用所需的所有功能构建尽可能好的站点,然后调整它,使其在旧版浏览器上工作。这可能比渐进式增强更难,效果也更差,但在某些情况下可能会有用。
用户代理的哪一部分包含您正在查找的信息
由于用户代理字符串的不同部分没有统一性,这是棘手的部分。
浏览器名称
当人们说他们想要“浏览器检测”时,通常他们实际上想要“渲染引擎检测”。您是否真的想检测Firefox,而不是SeaMonkey或Chrome,而不是Chromium?或者你真的只想看看浏览器是使用Gecko还是WebKit渲染引擎?如果这是您需要的,请参阅页面的更下方。
大多数浏览器都使用BrowserName / VersionNumber格式设置名称和版本,但Internet Explorer明显例外。但是,由于该名称不是该格式的用户代理字符串中的唯一信息,因此您无法发现浏览器的名称,只能检查您正在查找的名称。但请注意,有些浏览器在说谎:例如Chrome报告Chrome和Safari。因此,为了检测Safari,您必须检查Safari字符串以及Chrome字符串是否存在,Chromium经常将自己报告为Chrome,或者Seamonkey有时会将其自身报告为Firefox。
另外请注意,不要在BrowserName上使用简单的正则表达式,用户代理还包含Keyword / Value语法之外的字符串。例如,Safari和Chrome包含“像Gecko”这样的字符串。
必须包含 | 不得包含 | ||
---|---|---|---|
火狐 | 火狐/ XYZ | Seamonkey的/ XYZ | |
Seamonkey | Seamonkey的/ XYZ | ||
Chrome | Chrome / XYZ | Chromium / XYZ | |
Chromium | Chromium/ XYZ | ||
苹果浏览器 | Safari浏览器/ XYZ | Chrome / xyz或Chromium / xyz | Safari提供了两个版本号,一个是Safari / xyz标记中的技术,一个是用户友好的版本/ xyz标记 |
Opera | OPR / xyz 1 Opera / xyz 2 | 1 Opera 15+(基于闪烁的引擎)2 Opera 12-(基于Presto的引擎) | |
Internet Explorer | ; MSIE xyz; | Internet Explorer不会以BrowserName / VersionNumber格式放置其名称 |
当然,绝对不能保证其他浏览器不会劫持一些这样的东西(比如过去Chrome就劫持了Safari字符串)。这就是为什么使用用户代理字符串进行浏览器检测是不可靠的,只能通过检查版本号来完成(劫持过去版本的可能性较小)。
浏览器版本
浏览器版本通常(但并非总是)放入用户代理字符串中的BrowserName / VersionNumber标记的值部分。这对于Internet Explorer(将版本号恰好放在MSIE令牌之后)和Opera 10之后的Opera添加了版本/ 版本号令牌当然不是这种情况。
同样,请务必为您正在寻找的浏览器选择正确的标记,因为不能保证其他将包含有效的数字。
渲染引擎
如前所见,在大多数情况下,寻找渲染引擎是更好的方法。这将有助于不排除鲜为人知的浏览器。共享一个通用渲染引擎的浏览器将以同样的方式显示一个页面:一个公平的假设是,一个工作在另一个工作中。
有五个主要的渲染引擎:Trident,Gecko,Presto,Blink和WebKit。由于嗅探渲染引擎名称很常见,因此许多用户代理添加了其他渲染名称以触发检测。因此,在检测渲染引擎时注意不要触发误报。
必须包含 | ||
---|---|---|
壁虎 | 壁虎/ XYZ | |
WebKit | AppleWebKit / XYZ | 请注意,WebKit浏览器会添加一个'像Gecko'字符串,如果检测不够谨慎,可能会触发Gecko的误报。 |
Presto | Opera / XYZ | 注意:Presto不再用于Opera浏览器版本> =版本15(请参阅'闪烁') |
Trident | Trident / XYZ | Internet Explorer将此令牌放入用户代理字符串的注释部分 |
Trident | Chrome/ XYZ |
渲染引擎版本
大多数渲染引擎将版本号放入RenderingEngine / VersionNumber令牌中,但Gecko明显例外。Gecko将Gecko版本号放在rv:
字符串后面的User Agent的注释部分。从手机版的Gecko 14和桌面版的Gecko 17中,它也将这个值放在Gecko/version
令牌中(以前的版本中有构建日期,然后是一个名为GeckoTrail的固定日期)。
OS
操作系统在大多数用户代理字符串中给出(尽管不是像Firefox OS这样的网络集中式平台),但是格式各不相同。它是用户代理注释部分中两个分号之间的固定字符串。这些字符串对于每个浏览器都是特定的。它们表示操作系统,但也常常是其依赖硬件(32位或64位或Intel / PPC for Mac)的版本和信息。
就像在所有情况下一样,这些字符串将来可能会发生变化,应该将它们仅用于检测已发布的浏览器。当新的浏览器版本出现时,必须进行技术调查以适应脚本。
手机,平板电脑或桌面
执行用户代理嗅探的最常见原因是确定浏览器运行的设备类型。目标是为不同的设备类型提供不同的HTML。
- 切勿假设浏览器或渲染引擎仅在一种设备上运行。特别是不要为不同的浏览器或渲染引擎设置不同的默认值。
- 切勿使用OS令牌来定义浏览器是否在移动设备,平板电脑或台式机上。操作系统可能运行在多种类型的设备上(例如,Android可以在平板电脑以及手机上运行)。
下表总结了主要浏览器供应商表示其浏览器在移动设备上运行的方式:
浏览器 | 规则 | 例 |
---|---|---|
Mozilla(Gecko,Firefox) | 手机或平板电脑令牌在评论中。 | Mozilla / 5.0(Android; Mobile; rv:13.0)Gecko / 13.0 Firefox / 13.0 |
基于WebKit的(Android,Safari) | 评论之外的移动Safari标记。 | Mozilla / 5.0(Linux; U; Android 4.0.3; de-ch; HTC Sensation Build / IML74K)AppleWebKit / 534.30(KHTML,如Gecko)Version / 4.0 Mobile Safari / 534.30 |
基于闪烁(Chromium,Google Chrome,Opera 15+) | 评论之外的移动Safari标记 | Mozilla / 5.0(Linux; Android 4.4.2); Nexus 5 Build / KOT49H)AppleWebKit / 537.36(KHTML,如Gecko)Chrome / 33.0.1750.117 Mobile Safari / 537.36 OPR / 20.0.1396.72047 |
基于Presto(Opera 12-) | Opera中的Opera Mobi / xyz令牌(Opera 12-) | Opera / 9.80(Android 2.3.3; Linux; Opera Mobi / ADR-1111101157; U; es-ES)Presto / 2.9.201版本/ 11.50 |
Internet Explorer | IEMobile / xyz令牌的评论。 | Mozilla / 5.0(兼容; MSIE 9.0; Windows Phone OS 7.5; Trident / 5.0; IEMobile / 9.0) |
总之,我们建议在用户代理的任何位置查找字符串“Mobi”以检测移动设备。
如果设备足够大以至于没有标记“Mobi”,则应该为您的桌面站点提供服务(作为最佳做法,无论如何应该支持触摸输入,因为随着触摸屏出现更多台式机)。