用户代理字符串的发展历程
本片文章用户接受,用户代理字符串的一些历史。即通过 navigator.userAgent 访问得到的字符串。
HTTP规范(包括1.0 和 2.0)明确规定,浏览器应该发送简短的用户代理字符串,指明浏览器的名称和版本号。RFC2612(即HTTP1.1协议规范)是这样描述用户代理字符串的。
“产品标识符常用于通信应用程序标识自身,由软件名和版本组成。使用产品标识符的大多数领域也允许列出作为应用程序主要部分的子产品,由空格分割,按照惯例,产品要按照相应的重要程度依次列出,以便标识应用程序。”
上述规范进一步规定,字符串格式为:标识符 / 产品版本号。但是现实中的用户代理字符串绝没有这么简单。
1. 早期的浏览器
1993年,美国 NCSA( National Center for Supercomputing Applications, 国家超级计算机中心 )发布了世界上第一款 Web 浏览器 Mosaic。这款浏览器的用户代码字符串非常简单。如下:
Mosaic / 0.9
正斜杠前面表示产品名称,后面表示版本号
Netscape Communications(网景)公司介入浏览器开发领域后,将自己的产品的代码定名为 Mozilla( Mosaic Killer 的简写,意即 Mosaic杀手)。该公司的第一个公共发行版浏览器Netscape Navigator 2的用户代理字符串如下:
Mozilla / 版本号 [语言] (平台; 加密类型)
Netscape 在坚持将产品和版本号作为用户代理字符串开头的基础上,又在后面依次添加了下列信息。
- 语言:即语言代码,表示应用程序针对哪种语言设计。
- 平台:即操作系统和(或)平台,表示应用程序的允许环境
-
加密类型:即安全加密类型。可能的值有:
- U:123位加密
- I:40位加密
- N:未加密
典型的 Netscape Navigator2的用户代理字符串如下:
Mozilla / 2.02 [fr] (WinNT: I)
这个字符串是 Netscape Navigator 2.02,为法语国家编译,运行在 Windows NT平台下,加密类型为40位
2. Netscape Navigator 和 Internet Explorer3
1996年,Netscape Navigator 3 发布,随机超越Mosaic称为当时最流行的Web浏览器。而用户代理字符串只作了一些小的改变,删除了语言标记,同时允许添加操作系统或系统使用的CPU等可选信息。格式如下:
Mozilla/版本号 (平台; 加密类型 [; 操作系统或 CPU说明])
运行在 Windows 系统下的 Netscape Navigator 3 的用户代理字符串大致如下。
Mozilla/3.0 (win95; U)
表示 Netscape Navigator 3 运行在 Windows 95中,采用了 128位加密技术。可见,在Windows 系统中,字符串中的操作系统或CPU说明被省略了。
Netscaoe Navigator 3发布后不久,微软也发布了其第一款赢得用户广泛认可的 Web浏览器,即Internet Explorer 3。由于 Netscape 的浏览器在当视占绝对市场份额,许多服务器在提供网页之前都要专门检测浏览器。如果用户通过IE打不开相关网页,那么这个新生的浏览器很可能就会夭折。于是,微软绝定将IE的用户代理字符串修改成兼容 Netscape 的形式如下:
Mozilla/2.0 (compatible; MSIE 版本号; 操作系统)
例如,windows95平台下的 Internet Explorer 3.02带用如下用户代理字符串
Mozilla/2.0 (compatible; MSIE 3.02; windows 95)
由于当时大多数浏览器嗅探程序只坚持用户代理字符串中的产品名称部分,结果IE就成功地将自己标识位Mozilla,从而伪装成 Netscape Navigator。微软的这一做法招致了很多批评,因为它违反了浏览器标识的惯例。更不规范的是,IE将真正的浏览器版本号插入到字符串的中间。
字符串中另外一个有趣的地方是标识符 Mozilla 2.0(而不是3.0)。毕竟当视的主流版本是 3.0,改成3.0 应该对微软更有利才对。但是真正的谜底到现在还没有揭开——但很可能只是人为的疏忽。
3. Netscape Communicator 4 和 IE4~IE8
1997年 8月,Netscape Communicator 4发布(这一版将浏览器 名字中的 Navigator 换成了 Communicator)。Netscape继续遵循了第三版的用户代理字符串的格式:
Mozilla/版本号 (平台; 加密类型 [; 操作系统或CPU说明])
因此 Netscape Communicator4 在Windows 98平台中第四版的用户代理字符会如下:
Mozilla/4.0 (Win98; I)
Netscape在发布补丁时,自版本号也会相应的提高,用户代理字符串如下面的4.79版所示:
Mozilla/4.79 (Win98; I)
但是,微软在发布Internet Explorer4时,顺便将用户代理字符串修改成了如下格式:
Mozilla/4.0 (compatible; MSIE 版本号; 操作系统)
对于Windows 98中运行的IE4 而言,其用户代理字符串位:
Mozilla/4.0 (compatible; MSIE 4.0; Windows 98)
经过这次修改,Mozilla 版本号就与实际的IE版本号一致了,为识别它们的第四代浏览器提供了方便。但令人遗憾的是,两者的一致性仅限于这一个版本。在Internet Explorer4.5发布时(中针对于 Macs),Mozilla的版本号依然是4;
Mozilla/4.0 (compatible; MSIE 4.5; Mac_PowerPC)
此后,IE的版本一直到7都沿袭了这个模式:
Mozilla/4.0 (compatible; MSIE 4.5; Windows NT 5.1)
而IE8的用户代理字符串添加了呈现引擎(Trident)的版本号:
Mozilla/4.0 (compatible; MSIE 版本号; 操作系统; Trident/Trident 版本号)
例如:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
这个新增的 Trident 记号是为了让开发人员知道 IE8 是不是在兼容模式下运行。如果是,则MSIE的版本号会变成7, 但Trident 及版本号还会留在用户代码字符串中。
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0)
郑家这个记号有助于分辨浏览器到底是IE7(MSIE版本为7,且没有Trident记号),还是运行在兼容模式下的IE8(MSIE版本为7,有Trident记号)
IE9对字符串格式作了一点调整。Mozilla版本号增加到了5.0,而Trident的版本号也升到了5.0。:
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
这些变化都是为了确保过去的用户代理检测脚本能够继续发挥作用,同时还能给新脚本提供更丰富的信息。
4. Gecko
Gecko 是 Firefox 的呈现引擎。当场的Gecko 是作为通用的 Mozilla 浏览器的一部分开发的,而第一个采用 Gecko 引擎的浏览器是 Netscape 6。为Netscape6 编写了一份规范中规定了为了版本中用户代理字符串的构成。这个版本格式于4.x相比,有着很大的区别,如下:
Mozilla/Mozilla 版本号 (平台; 加密类型; 操作系统或CPU; 语言; 预先发行版本; Gecko/Gecko 版本号 应用程序或产品/应用程序或产品版本号)
这个明显复杂了很多的用户代理字符串中蕴含很多新想法。
字符串项 | 必需吗 | 说明 |
---|---|---|
Mozilla版本号 | 是 | Mozilla的版本号 |
平台 | 是 | 浏览器运行的平台。可能的值包括Windows、Mac和X1(指Unix的X窗口系统) |
加密类型 | 是 | 加密技术的乐喜:U(128位)、I(40位)、N(未加密) |
操作系统或CPU | 是 | 浏览器运行的操作系统或计算机系统使用的CPU。在Windows平台下指Windows的版本(如WinNT、Win95等待)。如果平台是Mac,指CPU(针对PowerPC的68K、PPC或NacIntel)。如果平台是X11,这一项是Unix操作系统的名称,于使用Unix命令uname-sm得到的名称相同。 |
语言 | 是 | 浏览器设计时所针对的用户语言 |
预先发行版本 | 否 | 最初用于表示Mozilla的预先发行版本,现在则用来表示Gecko程序引擎的版本号 |
Gecko版本号 | 是 | Gecko呈现引擎的版本号,但由yyyymmdd格式的日期表示 |
应用程序或产品 | 否 | 使用Gecko的产品名。可能是Netscape、Firefox等 |
应用程序或产品版本号 | 否 | 应用程序或产品的版本号;用于区分Mozilla版本号和Gecko版本号 |
为了更好理解Gecko的用户代理字符串,下面展示几个基于Gecko的浏览器中取得的字符串。
Windows XP 下的 Netscape 6.21:
Mozilla/5.0 (WIndows; U; Windows NT 5.1; en-US; rv:0.9.4) Gecko/20011128 Netscape6/6.2.1
Linux 下的 SeaMonkey 1.1a:
Mozilla/5.0 (X11; U; Linux 1689; en-US; rv:1.8.1b2) Gecko/20060832 SeaMonkey/1.1a
Windows XP 下的Firefox 2.0.0.11:
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11
Mac OS X 下的 Camino 1.5.1:
Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en; rv:1.8.1.6) Gecko/20070809 Camino/1.5.1
以上这些用户代理字符串都取自基于Gecko的浏览器(只是版本不同)。每个字符串中的Mozilla 版本都是5.0,自从第一个居于Gecko的浏览器发布时修改成这个样子,至今就没有改变过;而且,看起来以后似乎也不会有什么变化。
关于 Firefox 与 Netscape的关系。
到了 Windows 98时代将IE与Windows 98捆绑在一起免费提供,结果在很短的时间内Netscape的用户群体迅速萎缩,市场占有率急剧下降。面对微软的强大威胁,Netscape在1998年11月决定将软件免费、且公开所有的程序源码。这个措施几乎还没来得及实施, Netscape就被AOL美国在线所收购。AOL并非是想开发浏览器同微软的IE竞争,而是将它作为对微软的反垄断案的一个筹码。之后, Netscape虽然陆续发展出4.X、6.X系列乃至7.X系列,但都毫无影响力可言。微软与AOL的反垄断官司在2003年5月完结, Netscape项目在7月份就被AOL冻结并将大部分Netscape 开发人员解雇,到此为止属于Netscape的时代就完全结束了。不过AOL还是作了一件好事,所有的Netscape原始代码被送给开源社群自行开发,同时协助成立了非盈利性的“Mozilla基金会(Mozilla Foundation)”,它也是现在Firefox浏览器的管理和推进组织。
随着 Firefox 4 发布,Mozilla 简化了这个用户代理字符串。主要改变包括以下几方面。
- 删除了 “语言” 记号(例如,前面例子中的“en-US”)
- 在浏览器中使用强加密(U/128位,默认设置)时,不现实“加密类型”。也就是说(只有 I 、 N 会出现)
- “平台”记号从Windows 用户代理字符串中删除了,“操作系统或 CPU”中始终都包含“Windows”字符串
- “Gecko版本号” 固定为 “Gecko/20100101”
最后,Firefox4用户代理字符串变成下面这个样子:
Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox 4.0.1
5. Webkit
2003年,Apple公司宣布要发布自己的Web浏览器,名字为Safari。Safari的呈现引擎叫 Webkit,是 Linux 平台中 Konqueror 浏览器的呈现引擎 KHTML 的一个分支。几年后,WebKit 独立出来成为了一个开源项目,专注于呈现引擎的开发。
这款浏览器也遇到和IE3一样的问题;如何确保这款浏览器不会被流行的站点拒之门外?答案就是向用户代理字符串中放入足够多的信息,以便站点能够信任它与其他流行的浏览器是兼容的。
Mozilla/5.0 (平台; 加密类型; 操作系统或CPU; 语言) AppleWebkit/AppleWebKit版本号
实例:
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/123 (KHTML, like Gecko)
出于兼容性考虑,有关人员很快就决定将Safari标识为Mozilla。至今,基于Webkit的所有浏览器都将自己表示为Mozilla 5.0,与基于 Gecko 的浏览器完全一样。
Safari 预发行 1.0 版用户代理字符串中最耐人寻味,也是最饱受诟病的部分是字符串(KHTML like Gecko); Apple的回应与 IE最初时一样:Safari 与 Mozilla 兼容,因此网站不应该将 Safari 用户拒之门外,否则用户就会认为自己的浏览器不受支持。
Safari3.0发布时,增加了 Version 记号,沿用至今。
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebkit/622.15.5 (KHTML, like Gecko) Version/3.0.3 Safari/522.15.5
这个变化只有Safari中有,在Webkit 中没有。也就是说,其他基于webkit 的浏览器没有这个变化。
6. Konqueror
与 KDE Linux 继承的 Konqueror,是一款基于 KHTML 开源呈现引擎的浏览器。尽管Konqueror 只能在 Linux中使用,但它也有数量可观的用户。为了确保最大限度的兼容性,Konqueror效仿 IE 选择了如下用户代理字符串格式。
Mozilla/5.0 (compatible; Konqueror/ 版本号; 操作系统或CPU )
不过为了与Webkit的用户代理字符串的变化保持一致,Konqueror 3.2 又有了变化,以如下格式将自己标识位 KHTML
Mozilla/5.0 (compatible; Konqueror/3.5; SunOS) KHTML/3.5.0 (like Gecko)
其中,Konqueror 与 KHTML 的版本号比较一致,即使有差别也很小,例如 Konqueror 3.5使用 KHTML 3.5.1
Chrome
谷歌公司的 Chrome 浏览器以Webkit 作为呈现引擎,但使用了不同的JavaScript引擎(V8)。在Chrome0.2这个最初的beta版中,用户代理字符串完全取自 Webkit,只添加了一段表示 Chrome 版本号的信息,格式如下:
Mozilla/5.0 (平台; 加密类型; 操作系统 CPU; 语言) AppleWebkit/AppleWebkit版本号 (KHTML, like Gecko) Chrome/ Chrome 版本号 Safari/ Safari 版本
Chrome 7 的完整用户代理字符串如下:
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.44 Safari/534.7
其中,WebKit 版本 与 Safari 版本看起来似乎始终会保持一致,尽管没有十分的把握。
8. Opera
仅就用户代理字符串而言,Opera 应该是最有争议的一款浏览器了。Opera 默认的用户代理字符串时所有现代浏览器中最合理的——正确地标识了自身及其版本号。在Opera8.0之前,采用如下格式:
Opera/ 版本号 (操作系统或CPU; 加密类型) [语言]
Windows XP中的 Opera7.54 会显示如下用户代理字符串:
Opera/7.54 (Windows NT 5.1; U) [en]
Opera8发布以后,用户代理字符串的“语言”部分被移到圆括号内,以便更好地与其他浏览器匹配,如下:
Opera/版本号 (操作系统或CPU; 加密类型; 语言)
Windows XP中的Opera 8 会显示下面的用户代理字符串:
Opera/8.0 (Windows Nt 5.1; U; en)
默认情况下,Opera会以上面这种简单的格式返回一个用户代理字符串。目前来看,Opera也是主要浏览器中唯一一个使用产品名和版本号来完全彻底标识自身的浏览器。Opera没有选择通过修改自身的用户代理字符串来迷惑嗅探代码,而实干脆选择通过修改自身的用户代理字符串将自身标识位一个完全不同的浏览器。
Opera9以后,出现了两种修改自身用户代理字符串的方式
第一种:将自身标识位另一个浏览器,如Firefox 或者 IE。在这情况下,用户代理字符串就如同 其他浏览器的 用户代理字符串一样,只不过末尾追加了字符串 Opera 及 Opera的版本号,如下:
Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50
以上分别标识位 Firefox 2, IE6
第二种:就是把自己装扮成Firefox或IE。在这种隐瞒真实身份的情况下,既没有Opera字样,也不包含Opera的版本信息。另外,由于Opera喜欢在不告知用户的情况下针对站点来设置用户代理字符串,因此问题就更复杂化了。例如:打开 MyYahoo!站点(http://my.yahoo.com)会自动导致Opera将自己装扮成 Firefox。如此依赖,想要识别Opera就难上加难了。
在 Opera10中对代理字符串进行了修改。现在的格式是:
Opera/9.80 (操作系统或CPU; 加密类型; 语言) Presto/Presto 版本号 Version/版本号
初始版本号 Opera/9.80 是固定不变的。实际并没有 Opera 9.8,但工程师们担心写得不好的浏览器嗅探脚本会将 Opera/10.0 错误的解释位 Opera 1, 因此,Opera 10又增加了Presto记号( Presto 是 Opera 的呈现引擎) 和 Version 记号。
以下是Windows 7 中 Opera 10.63 的用户代理字符串:
Opera/9.08 (windows NT 6.1; U; en) Presto/2.6.30 Version/10.63
ISO 和 Android
移动早做系统ISO 和 Android 默认的浏览器都基于 WebKit,而且都像它们的桌面版一样,共享相同的基本用户代理字符串格式。ISO设备的基本格式如下:
Mozilla/5.0 (平台; 加密类型; 操作系统或CPU like Mac OS X; 语言) AppleWebKit/AppleWebKit 版本号 (KHTML, like Gecko) Version/浏览器版本号 Mobile/移动版本号 Safari/Safari 版本号
注意用于辅助确定 Mac 操作系统的 “like Mac OS X”和额外的 Mobile记号。Mobile主要是用来确定 Webkit是移动版,而非桌面版。
Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us ) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16
在IOS3之前,用户代理字符串中不会出现操作系统版本号
Android浏览器中的默认格式与IOS的格式相似,没有移动版本号(但又Mobile记号)。例如:
Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
以上是Google Nexus One 手机的用户代理字符串。不过其他Android 设备的模式也一样。