javascript基础学习系列三百九十七:用户代理检测

用户代理检测通过浏览器的用户代理字符串确定使用的是什么浏览器。用户代理字符串包含在每个HTTP 请求的头部,在 JavaScript 中可以通过 navigator.userAgent 访问。在服务器端,常见的做法是根据接收到的用户代理字符串确定浏览器并执行相应操作。而在客户端,用户代理检测被认为是不可靠的,只应该在没有其他选项时再考虑。
用户代理字符串最受争议的地方就是,在很长一段时间里,浏览器都通过在用户代理字符串包含错误或误导性信息来欺骗服务器。要理解背后的原因,必须回顾一下自 Web 出现之后用户代理字符串的历史。用户代理的历史HTTP 规范(1.0 和 1.1)要求浏览器应该向服务器发送包含浏览器名称和版本信息的简短字符串。
RFC 2616(HTTP 1.1)是这样描述用户代理字符串的:
产品标记用于通过软件名称和版本来标识通信产品的身份。多数使用产品标记的字段也允许列出属于应用主要部分的子产品,以空格分隔。按照约定,产品按照标识应用重要程度的先后顺序列出。
这个规范进一步要求用户代理字符串应该是“标记/版本”形式的产品列表。但现实当中的用户代理字符串远没有那么简单。
早期浏览器
美国国家超级计算应用中心(NCSA,National Center for Supercomputing Applications)发布于 1993年的 Mosaic 是早期 Web 浏览器的代表,其用户代理字符串相当简单,类似于:

虽然在不同操作系统和平台中可能会有所不同,但基本形式都是这么简单直接。斜杠前是产品名称(有时候可能是“NCSA Mosaic”之类的),斜杠后是产品版本。
在网景公司准备开发浏览器时,代号确定为“Mozilla”(Mosaic Killer 的简写)。第一个公开发行版Netscape Navigator 2 的用户代理字符串是这样的:

网景公司遵守了将产品名称和版本作为用户代理字符串的规定,但又在后面添加了如下信息。
 Language:语言代码,表示浏览器的目标使用语言。
 Platform:表示浏览器所在的操作系统和/或平台。
 Encryption:包含的安全加密类型,可能的值是 U(128 位加密)、I(40 位加密)和 N(无加密)。
Netscape Navigator 2 的典型用户代理字符串如下所示:

这个字符串表示 Netscape Navigator 2.02,在主要使用法语地区的发行,运行在 Windows NT 上,40 位加密。总体上看,通过产品名称还是很容易知道这是什么浏览器的。
Netscape Navigator 3 和 IE3 1996 年,Netscape Navigator 3 发布之后超过 Mosaic 成为最受欢迎的浏览器。其用户代理字符串也发生了一些小变化,删除了语言信息,并将操作系统或系统 CPU 信息(OS-or-CPU description)等列为可选信息。此时的格式如下:

运行在 Windows 系统上的 Netscape Navigator 3 的典型用户代理字符串如下:

这个字符串表示 Netscape Navigator 3 运行在 Windows 95 上,采用了 128 位加密。注意在 Windows系统上,没有“OS-or-CPU”部分。
Netscape Navigator 3 发布后不久,微软也首次对外发布了 IE3。这是因为当时 Netscape Navigator 是市场占有率最高的浏览器,很多服务器在返回网页之前都会特意检测其用户代理字符串。如果 IE 因此打不开网页,那么这个当时初出茅庐的浏览器就会遭受重创。为此,IE 就在用户代理字符串中添加了兼容 Netscape 用户代理字符串的内容。结果格式为:

比如,Windows 95 平台上的 IE3.02 的用户代理字符串如下:

当时的大多数浏览器检测程序都只看用户代理字符串中的产品名称,因此 IE 成功地将自己伪装成
了 Mozilla,也就是 Netscape Navigator。这个做法引发了一些争议,因为它违反了浏览器标识的初衷。
另外,真正的浏览器版本也跑到了字符串中间。
这个字符串中还有一个地方很有意思,即它将自己标识为 Mozilla 2.0 而不是 3.0。3.0 是当时市面上使用最多的版本,按理说使用这个版本更合逻辑。背后的原因至今也没有揭开,不过很可能就是当事人一时大意造成的。
Netscape Communicator 4 和 IE4~8
1997 年 8 月,Netscape Communicator 4 发布(这次发布将 Navigator 改成了 Communicator)。Netscape在这个版本中仍然沿用了上一个版本的格式:

比如,Windows 98 上的第 4 版,其用户代理字符串就是这样的:

如果发布了补丁,则相应增加版本号,比如下面是 4.79 版的字符串:

微软在发布 IE4 时只更新了版本,格式不变:

比如,Windows 98 上运行的 IE4 的字符串如下:

更新版本号之后,IE 的版本号跟 Mozilla 的就一致了,识别同为第 4 代的两款浏览器也方便 了。可是,这种版本同步就此打住。在 IE4.5(只针对 Mac)面世时,Mozilla 的版本号还是 4,IE 的版本号却变了:

直到 IE7,Mozilla 的版本号就没有变过,比如:

IE8 在用户代理字符串中添加了额外的标识“Trident”,就是浏览器渲染引擎的代号。格式变成:

比如:

这个新增的“Trident”是为了让开发者知道什么时候 IE8 运行兼容模式。在兼容模式下,MSIE 的版本会变成 7,但 Trident 的版本不变:

添加这个标识之后,就可以确定浏览器究竟是 IE7(没有“Trident”),还是 IE8 运行在兼容模式。IE9 稍微升级了一下用户代理字符串的格式。Mozilla 的版本增加到了 5.0,Trident 的版本号也增加到了 5.0。IE9 的默认用户代理字符串是这样的:

如果 IE9 运行兼容模式,则会恢复旧版的 Mozilla 和 MSIE 版本号,但 Trident 的版本号还是 5.0。比如,下面就是 IE9 运行在 IE7 兼容模式下的字符串:

所有这些改变都是为了让之前的用户代理检测脚本正常运作,同时还能为新脚本提供额外的信息。
Gecko
Gecko 渲染引擎是 Firefox 的核心。Gecko 最初是作为通用 Mozilla 浏览器(即后来的 Netscape 6)的一部分开发的。有一个针对 Netscape 6 的用户代理字符串规范,规定了未来的版本应该如何构造这个字符串。新的格式与之前一直沿用到 4.x 版的格式有了很大出入:

 PrereleaseVersion)Gecko/GeckoVersion
 ApplicationProduct/ApplicationProductVersion 

这个复杂的用户代理字符串包含了不少想法。下表列出了其中每一部分的含义。

MozillaVersion 是 Mozilla 版本
Platform 是 浏览器所在的平台。可能的值包括 Windows、Mac 和 X11(UNIX XWindows)Encryption 是 加密能力:U 表示 128 位,I 表示 40 位,N 表示无加密OS-or-CPU 是 浏览器所在的操作系统或计算机处理器类型。如果是 Windows 平台,则这里是 Windows 的版本(如 WinNT、Win95)。如果是 Mac 平台,则这里是 CPU 类型(如 68k、PPC for PowerPC 或 MacIntel)。如果是 X11平台,则这里是通过 uname -sm 命名得到的 UNIX 操作系统名
Language 是 浏览器的目标使用语言Prerelease Version 否 最初的设想是 Mozilla预发布版的版本号,现在表示 Gecko 引擎的版本号GeckoVersion 是 以 yyyymmdd 格式的日期表示的 Gecko 渲染引擎的版本
ApplicationProduct 否 使用 Gecko 的产品名称。可能是 Netscape、Firefox 等ApplicationProductVersion 否 ApplicationProduct 的版本,区别于 MozillaVersion 和 GeckoVersion

要更好地理解 Gecko 的用户代理字符串,最好是看几个不同的基于 Gecko 的浏览器返回的字符串。Windowx XP 上的 Netscape 6.21:

 Netscape6/6.2.1 

Linux 上的 SeaMonkey 1.1a:

Windows XP 上的 Firefox 2.0.0.11:

 Firefox/2.0.0.11 

Mac OS X 上的 Camino 1.5.1:

 Camino/1.5.1

所有这些字符串都表示使用的是基于 Gecko 的浏览器(只是版本不同)。有时候,相比于知道特定的浏览器,知道是不是基于 Gecko 才更重要。从第一个基于 Gecko 的浏览器发布开始,Mozilla 版本就是 5.0,一直没有变过。以后也不太可能会变。
在 Firefox 4 发布时,Mozilla 简化了用户代理字符串。主要变化包括以下几方面。
 去掉了语言标记(即前面例子中的"en-US")。
 在浏览器使用强加密时去掉加密标记(因为是默认了)。这意味着 I 和 N 还可能出现,但 U 不可能出现了。
 去掉了 Windows 平台上的平台标记,这是因为跟 OS-or-CPU 部分重复了,否则两个地方都会有Windows。
 GeckoVersion 固定为"Gecko/20100101"。
下面是 Firefox 4 中用户代理字符串的例子:

  • 23
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值