浏览器UA mozilla/5.0发展史

你是否好奇标识浏览器身份的User-Agent,为什么每个浏览器都有Mozilla字样?


Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36
Mozilla/5.0 (Linux; U; Android 4.1.2; zh-tw; GT-I9300 Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:20.0) Gecko/20100101 Firefox/20.0

Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0)


故事还得从头说起,最初的主角叫NCSA Mosaic,简称Mosaic(马赛克),是1992年末位于伊利诺伊大学厄巴纳-香槟分校的国家超级计算机应用中心(National Center for Supercomputing Applications,简称NCSA)开发,并于1993年发布的一款浏览器。它自称“NCSA_Mosaic/2.0(Windows 3.1)”,Mosaic可以同时展示文字和图片,从此浏览器变得有趣多了。

然而很快就出现了另一个浏览器,这就是著名的Mozilla,中文名称摩斯拉。一说 Mozilla = Mosaic + Killer,意为Mosaic杀手,也有说法是 Mozilla = Mosaic & Godzilla,意为马赛克和哥斯拉,而Mozilla最初的吉祥物是只绿色大蜥蜴,后来更改为红色暴龙,跟哥斯拉长得一样。


但Mosaic对此非常不高兴,于是后来Mozilla更名为Netscape,也就是网景。Netscape自称“Mozilla/1.0(Win3.1)”,事情开始变得更加有趣。网景支持框架(frame),由于大家的喜欢框架变得流行起来,但是Mosaic不支持框架,于是网站管理员探测user agent,对Mozilla浏览器发送含有框架的页面,对非Mozilla浏览器发送没有框架的页面。


后来网景拿微软寻开心,称微软的Windows是“没有调试过的硬件驱动程序”。微软很生气,后果很严重。此后微软开发了自己的浏览器,这就是Internet Explorer,并希望它可以成为Netscape Killer。IE同样支持框架,但它不是Mozilla,所以它总是收不到含有框架的页面。微软很郁闷很快就沉不住气了,它不想等到所有的网站管理员都了解IE并且给IE发送含有框架的页面,它选择宣布IE是兼容Mozilla,并且模仿Netscape称IE为“Mozilla/1.22(compatible; MSIE 2.0; Windows 95)”,于是IE可以收到含有框架的页面了,所有微软的人都嗨皮了,但是网站管理员开始晕了。


因为微软将IE和Windows捆绑销售,并且把IE做得比Netscape更好,于是第一次浏览器血腥大战爆发了,结果是Netscape以失败退出历史舞台,微软更加嗨皮。但没想到Netscape居然以Mozilla的名义重生了,并且开发了Gecko,这次它自称为“Mozilla/5.0(Windows; U; Windows NT 5.0; en-US; rv:1.1) Gecko/20020826”。

Gecko是一款渲染引擎并且很出色。Mozilla后来变成了Firefox,并自称“Mozilla/5.0 (Windows; U; Windows NT 5.1; sv-SE; rv:1.7.5) Gecko/20041108 Firefox/1.0”。Firefox性能很出色,Gecko也开始攻城略地,其他新的浏览器使用了它的代码,并且将它们自己称为“Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.2) Gecko/20040825 Camino/0.8.1”,以及“Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.8) Gecko/20071008 SeaMonkey/1.0”,每一个都将自己装作Mozilla,而它们全都使用Gecko。


Gecko很出色,而IE完全跟不上它,因此user agent探测规则变了,使用Gecko的浏览器被发送了更好的代码,而其他浏览器则没有这种待遇。Linux的追随者对此很难过,因为他们编写了Konqueror,它的引擎是KHTML,他们认为KHTML和Gecko一样出色,但却因为不是Gecko而得不到好的页面,于是Konqueror为得到更好的页面开始将自己伪装成“like Gecko”,并自称为“Mozilla/5.0 (compatible; Konqueror/3.2; FreeBSD) (KHTML, like Gecko)”。自此user agent变得更加混乱。


这时更有Opera跳出来说“毫无疑问,我们应该让用户来决定他们想让我们伪装成哪个浏览器。”于是Opera干脆创建了菜单项让用户自主选择让Opera浏览器变成“Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.51”,或者“Mozilla/5.0 (Windows NT 6.0; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.51”, 或者“Opera/9.51 (Windows NT 5.1; U; en)”。


后来苹果开发了Safari浏览器,并使用KHTML作为渲染引擎,但苹果加入了许多新的特性,于是苹果从KHTML另辟分支称之为WebKit,但它又不想抛弃那些为KHTML编写的页面,于是Safari自称为“Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-de) AppleWebKit/85.7 (KHTML, like Gecko) Safari/85.5”,这进一步加剧了user agent的混乱局面。

因为微软十分忌惮Firefox,于是IE重装上阵,这次它自称为“Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ”,并且渲染效果同样出色,但是需要网站管理员的指令它这么做才行。


再后来,谷歌开发了Chrome浏览器,Chrome使用Webkit作为渲染引擎,和Safari之前一样,它想要那些为Safari编写的页面,于是它伪装成了Safari。于是Chrome使用WebKit,并将自己伪装成Safari,WebKit伪装成KHTML,KHTML伪装成Gecko,最后所有的浏览器都伪装成了Mozilla,这就是为什么所有的浏览器User-Agent里都有Mozilla。Chrome自称为“Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13”。

因为以上这段历史,现在的User-Agent字符串变得一团糟,几乎根本无法彰显它最初的意义。追根溯源,微软可以说是这一切的始作俑者,但后来每一个人都在试图假扮别人,最终把User-Agent搞得混乱不堪。


一句话结论:因为网站开发者可能会因为你是某浏览器(这里是 Mozilla),所以输出一些特殊功能的程序代码(这里指好的特殊功能),所以当其它浏览器也支持这种好功能时,就试图去模仿 Mozilla 浏览器让网站输出跟 Mozilla 一样的内容,而不是输出被阉割功能的程序代码。大家都为了让网站输出最好的内容,都试图假装自己是 Mozilla 一个已经不存在的浏览器……


附各大浏览器诞生年表:
1993年1月23日:Mosaic
1994年12月:Netscape
1994年:Opera
1995年8月16日:Internet Explorer
1996年10月14日:Kongqueror
2003年1月7日:Safari
2008年9月2日:Chrome
注:本文转自简明现代魔法。
### Python 中 `try-except` 的用法与错误处理 在 Python 编程中,`try-except` 是一种用于捕获和处理异常的关键结构。它允许程序在遇到运行时错误时不立即崩溃,而是通过定义的逻辑来优雅地处理这些情况。 #### 基本语法 以下是 `try-except` 结构的基本形式: ```python try: # 可能引发异常的代码块 except SomeExceptionType as e: # 处理特定类型的异常 finally: # 不管是否有异常都会执行的代码块 ``` #### 示例分析 考虑以下函数实现中的异常处理机制[^2]: ```python def test_func(): try: x = 10 print(f" Inside try block ") return x except Exception as e: x = 20 print(f" Inside except block ") return x finally: x = 30 print(f" Inside finally block ") return x print(test_func()) ``` 上述代码展示了如何使用 `try`, `except`, 和 `finally` 来控制不同场景下的行为。具体来说: - **Try Block**: 此部分包含可能抛出异常的代码,在此例子中尝试赋值并返回变量 `x`。 - **Except Block**: 如果发生任何未预期的情况,则进入该分支;这里假设捕捉到通用异常类型 `Exception` 并设置默认值给 `x`. - **Finally Block**: 这一段无论前面是否触发异常均会被调用,通常用来释放资源或者清理操作。最终输出显示即使存在其他返回语句,“Inside finally block”仍被执行,并且最后实际返回的是来自 `finally` 部分的结果即数值 `30`. #### 错误处理的重要性 有效的错误管理对于构建健壮的应用至关重要。当应用程序面对不可预见状况时——比如文件读取失败、网络请求超时等——如果没有适当措施应对这些问题的话就可能导致整个应用停止运作甚至数据丢失等问题的发生。因此合理运用像上面提到过的那些方法可以帮助我们更好地掌控可能出现的各种意外情形从而提高软件质量以及用户体验满意度等方面都有很大帮助作用。 #### 用户代理字符串解析实例 另一个关于异常处理的例子涉及到HTTP头信息里的User-Agent字段解释如下所示[^4]: ```python import re ua_string = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1" pattern = r'\((.*?)\)' match = re.search(pattern, ua_string) if match is not None: os_info = match.group(1) else: raise ValueError("No OS information found.") print(os_info) ``` 在这个脚本里如果正则表达式匹配不到相应的操作系统详情就会抛出自定义的价值观错识(ValueError),这样可以提醒开发者注意输入的数据格式不符合期待标准以便及时修正源头上的失误之处而不是让系统默默吞掉这个潜在隐患继续往下走造成更多难以追踪定位的技术债累积起来以后再改成本会更高也更麻烦复杂得多出来。 ### 总结注意事项 总结一下多线程池关闭参数说明及其重要考量因素有以下几个方面[^5]: - shutdown(wait=True): 关闭执行器并释放资源。如果wait设为True将会等待所有任务完成之后才真正结束进程。 主要关键字包括但不限于最大工作数(max_workers), 耐心等候时间长度(timeout). 综上所述可以看出无论是简单的局部测试还是复杂的跨平台交互都需要精心设计好各自的差错预案才能确保整体架构稳定可靠长期可用下去不断满足日益增长变化的需求挑战面前立于不败之地赢得市场先机占据有利位置持续发展进步壮大规模效益最大化目标达成共赢局面形成良性循环促进生态繁荣昌盛未来可期前景光明无限美好值得期待憧憬向往追求奋斗努力拼搏进取成就非凡伟业留名青史传颂千古流芳百世敬仰学习效仿传承弘扬光大贡献社会造福人类共同创造更加辉煌灿烂美好的明天!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值