一条从未中断的线
前面两章我们花了很大的精力来描述一个17年前创建 HTML 元素的讨论的经过,而这个元素今天已经出现在几乎所有的 web 页面之上。那么,现在我们总结一下:
- HTTP 依然存在。HTTP 成功地从 0.9 版本升级到 1.0,后来是 1.1,现在它仍在升级。
- HTML 依然存在。那个最起码的数据类型——甚至连内联图像都不支持——已经成功升级到 2.0,3.2,4.0。HTML 是一条从未中断的线,并且是一条纠结打结的线。在进化过程中出现了很多“死掉的”分支,这些通常是由于人们的想法过于超前造成的(超前于标准制定者和实现者)。但是,在今天2011年,1990年的页面依然能够在现代浏览器中正常的浏览。当我使用现在最先进的智能手机去浏览这种页面时,甚至连“请稍等,正在加载旧的格式...”这种提示都没有看到。
- 一直以来,HTML 都在浏览器制造商、网页作者、标准制定者以及其他相关人员之间转换进化着。很多成功的 HTML 版本都是“复古标准”,以便及时跟上浏览器发展的步伐。如果有人告诉你,HTML 应该保持“纯洁(纯洁的含义是,排除一切浏览器制造商、网页作者等等)”,那么他实际是在误导你。HTML 从来没有纯洁过,任何希望它纯洁的努力最后都是失败的。
- 1993年的浏览器现在差不多都已经不见踪影。Netscape Navigator 1998年被放弃,重新编写了 Mozilla Suite,后来的一个分支创建了 Firefox。Internet Explorer 在 Microsoft Plus! for Windows 95 才被引入活动桌面和一个简单的游戏中(当然,这个浏览器还能追溯到更早的时间)。
- 1993年的操作系统有些现在还存在,但是它们都没有与现代 web 有任何关联。今天很多人都是在一台运行着 Windows 2000 或其更新版本的 PC 上,或者是一台运行着 Mac OS X 的 Mac 上,或者运行着某个版本的 Linux 的 PC 上,或者手持设备比如 iPhone 上“体验”网络。在1993年,Windows 版本还是 3.1(与 OS/2 竞争的版本),Mac 还在运行 System 7,Linux 才在 Usenet 上发布。
- 仍然有些人现在还在参与到被称为“web 标准”的工作中来。这已经持续了大约20年。有些人在上世纪80年代或更早的时候还出在 HTML 的早期,谈论着 HTML 的前辈。当 HTML 统治了 web 之后,我们很容易忘记了其他类似目的的系统,比如 Andrew,比如 Intermadia,比如 HyTime。不过,HyTime 不仅仅是一个研究性项目,它实际上是 ISO 的一个标准。这才是一个真正的大事件,也正因为这个原因,你才能在你的浏览器中读着这篇使用 HTML 编写的文章。
那么,让我们再回到最初的问题上,“我们为什么需要一个<img>
元素?为什么不是<icon>
?为什么不是<include>
?为什么不是增加了 include 属性的<a>
?为什么非得是<img>
?”答案很简单,因为 Marc Andreessen 把它实现了出来。
这并不是说只要能实现出来就可以。毕竟,Andrew,Intermedia 和 HyTime 都有实现代码。代码是必要条件但不是充分条件。当然,我不是说在标准之前就把代码实现出来才是最好的解决方案。Marc 的<img>
元素没有指定通用的图像格式,也没有定义文本需要如何围绕,也不支持替换文本。17年之后,我们仍在内容协商的问题上挣扎,至今这仍然是一个棘手的问题。不过,现在你可以追溯到17年前的1993年2月25日,看看 Marc Andreessen 不经意写下的“或许是 MIME”,然后再将它实现出来。
胜利者是那些被实现出来的。
1997年~2004年HTML的发展
1997年12月,World Wide Web Consortium (W3C) 发布了 HTML 4.0,同时关闭了 HTML 工作组(HTML Working Group)。不到两个月,一个独立的 W3C 工作组发布了 XML 1.0。差不多三个月的时间中,人们一直在问,W3C 是不是放弃 HTML 了?针对这个问题,W3C 成立了一个工作室,叫做“Shaping the Future of HTML”,来回答这个问题。他们的答案是:
经过讨论,相比于将 HTML 4.0 迁移到一个 XML 应用而言,扩展 HTML 4.0 是相当困难的。最好的方式是打破现有枷锁,使用基于 XML 标签集合来做一个全新的下一代 HTML。
W3C 重新成立了 HTML 工作组,来创建这个“XML 标签集合”。1998年12月,他们的第一步工作已经完成。这个成果没有增加任何新的元素或属性,仅仅是将 HTML 使用 XML 作格式化。这一标准后来被成为“XHTML 1.0”。它引入了一个新的 MIME 类型,application/xhtml+xml。但是,为了迁移现有的 HTML 4 页面,必须按照一定的设计规范重新编写整个文档。当然,我们也有方法创建一个所谓的“XHTML”页面,但是依然保存为 text/html MIME 类型。
他们的下一个工作是 web 表单。在1999年8月,还是这一个 HTML 工作组发布了第一个 XHTML Extended Forms 草案。在第一段中,他们这样写道:
经过仔细思考,HTML 工作组决定下一代表单与现有的 HTML 表单不兼容。这能够让我们提供一个新的良格式的表单模型,也就是 XHTML Extended Forms。这要求本文档需要建立一个非常庞大的表单应用程序标准。
几个月之后,“XHTML Extended Forms”更名为“XForms”,并且有了专门的工作组。这一工作组与 HTML 工作组并行,最终在2003年10月发布了XForms 1.0。
同时,要将 HTML 完全迁移到 XML 上,HTML 工作组仍然关注于创建“下一代 HTML”。2001年5月,他们发布了XHTML 1.1,在 XHTML 1.0 的基础上增加了少数几个小的特性。从 1.1 开始,所有的 XHTML 文档都必须保存为 application/xhtml+xml 的 MIME 格式。
你所想象的一切关于 XHTML 的知识可能都是错的
为什么 MIME 类型这么重要?为什么我反复强调 MIME?原因在于:严格的错误处理。浏览器通常会“尽量解释” HTML。如果你创建了一个 HTML 页面,但是忘记写</head>
标签,浏览器无论如何都会将它显示出来(判断<head>
和<body>
之间的位置)。你希望正确的嵌套标签,按照“后进先出”的顺序,但如果你创建了<b><i></b></i>
这种,浏览器还是会很好的处理它,不会给出错误信息。
正如你想到的那样,浏览器对于“坏的” HTML 标记的放任态度,让很多页面作者去创建这种页面,从而有很多这种错误页面。据统计,现在网络上超过 99% 的 HTML 页面都至少存在一个错误。但是这些错误不会引起浏览器显示异常,因此没人愿意修改它们。
W3C 意识到这种放任的态度肯定会影响到 web 的发展,因此决定改正它们。1997年发布的 XML 要求人们必须编写所谓“良格式”的 XML 文档,否则的话会当做是一个致命错误。这种错误处理方式就是“严格的错误处理”。当 W3C 决定使用 XML 格式的 HTML 时,他们就增加了新的 MIME 类型 application/xhtml+xml 来引发严格的错误处理。甚至你的 XHTML 页面仅有一个不是良格式的,比如忘记了</head>
或者不正确的嵌套,浏览器都别无选择地停止继续解析页面,并且向用户显示一个错误信息。
这一思想并没有被广泛接受。原因在于 99% 的页面都存在错误,因此几乎所有页面都会对用户显示错误信息。没有人愿意为遵循一个标准而去修改所有页面,XHTML 1.0 和 1.1 的 application/xhtml+xml 就这么被广大用户抛弃了。然而,并不是 XHTML 所有都被抛弃。人们选择的是使用 XHTML 语法编写页面,但是依然保存为 text/html MIME 类型。这就是成千上万的 web 开发者做的事:“升级到” XHTML,但仍然保存为 text/html MIME 类型。
甚至今天,数百万的页面也都不是真正的 XHTML。它们第一行使用 XHTML doctype,使用小写标签名,使用引号引起来属性值,使用斜线关闭空元素,例如<br />
和<hr />
。但是,XHTML 最重要的一点,application/xhtml+xml 却没有继承下来,因此,即便你所谓的 XHTML 页面不是良格式的,浏览器也不会有致命错误。只要是 text/html 类型的页面,不管它的 doctype、语法或者代码风格如何,都会使浏览器使用“宽松的” HTML 解析器解析。
XHTML 1.0 引入了这一漏洞(也就是 XHTML 可以存为 text/html MIME 类型),XHTML 1.1 将其关闭。那个从未制定完成的 XHTML 2.0 则延续严格错误处理这一传统。这就是为什么现在有这么多的 XHTML 1.0 的页面,却很难见到 xhtml 1.1 (或者 XHTML 2.0)的页面。那么我们不禁要问,你用的真的是 XHTML 吗?检查一下你的 MIME 类型吧(事实上,即便你不知道你的 MIME 类型,我敢打赌,它一定是 text/html)!只有你将页面的 MIME 类型设置为 application/xhtml+xml,你才真正对得起 XHTML 这个名字中的代表 XML 的那个“X”!