HTML - embed 与 object 之争

  在 HTML 里嵌入文本和图片之外的事物,就会用到嵌入标签,而嵌入标签在各浏览器之间的不统一,一直是让开发人员很头痛的问题。一切都要从嵌入 SUN 公司的 Applet Java 小程序开始。

  当时,对于 Applet 的嵌入,浏览器老大哥 Netscape 公司是使用 embed 标签的,embed 标签的好处就是嵌入一个对象只需要一对标签,所有参数都写入该标签的属性,非常方便。而微软和其他浏览器厂商都使用 applet 专用标签,主标签只有几个固定的属性,那些和嵌入内容有关的属性都放在子标签 param 里(param 只有 name、value 这类固定属性),这种组合标签,就是 object 标签的前身。

  之后,随着 Flash、视频、音频这些多媒体元素在网站上的出现,embed 标签的功能被扩展了,用于嵌入这些多媒体元素——原先 embed 标签就有一个 type 属性,利用 MIME 分辨嵌入内容的类型——这是一个非常好的功能,使得非 Applet 的内容也能被识别,而且 MIME 的法则本身就不受浏览器和操作系统的限制。

  此时的微软,正在 ActiveX 技术普及的时期,applet 这种标签名范围太窄,于是就大力推行泛用的 object 标签,专门用于 ActiveX 控件的嵌入。object 标签几乎和 applet 一样,只是多了 clsid、codetype 等属性,主要用来来判别嵌入内容的类型。ActiveX 是一把双刃剑,虽然极易开发和使用,但是却是 Windows On ly 的技术;而且连 Firefox 的 Windows 版都不支持它,所以在浏览器行业 ActiveX 简直是 IE On ly……于是各大浏览器厂商都倒向以往被冷落的 embed,只是……被 W3C 认可的是 object,而不是 embed,因为 embed 的属性是根据嵌入内容类型的不同而不同的(实质上是针对“嵌入内容解读插件”而写的属性),无法定死,对于标准来说这就是硬伤。

  下面,我针对 embed 与 object 标签在 IE6 和 FF3 for Windows 之间做了对比测试。方法是,嵌入了一个 Flash(swf 文件,MIME 为 application/x-shockwave-flash)和一个音频(mp3 文件,MIME 为 audio/mpeg),分别写成四种形式的 HTML 给两个浏览器浏览:
  1,两个嵌入都使用 embed;
  2,两个嵌入都使用 object(只靠 clsid 识别);
  3,两个嵌入都使用 object(同时使用 clsid 与 codetype 识别);
  4,两个嵌入都使用 object(只靠 codetype 识别)。
  IE6 的结果为:
  1——两个嵌入都正常(mp3 默认是 WMP 的 ActiveX 控件打开;若 QuickTime ActiveX 控件注册了mp3 的 MIME,则由 QuickTime ActiveX 控件打开,且可能有安全警告);
  2——两个嵌入都正常(clsid 填写哪个 ActiveX 控件的,就用哪个打开);
  3——两个嵌入都正常(clsid 填写哪个 ActiveX 控件的,就用哪个打开);
  4——Flash 嵌入正常,mp3 音频嵌入失败(显示成一个无法输入的文本框)。
  FF3 的结果为:
  1——两个嵌入都正常(mp3 默认无法打开,除非 type 属性改用 WMP 专用 MIME;若 QuickTime 插件注册了mp3 的 MIME,则由 QuickTime 插件打开);
  2——两个嵌入都失败(空白);
  3——两个嵌入都失败(空白);
  4——两个嵌入都失败(空白)。

  测试结果是:embed 标签兼容性较强,但是变数太多,对于小白浏览者来说就是噩梦;而 object 标签果然是 IE On ly。所以当年被 Macromedia 公司所提倡的 object-embed 混合写法是最安全的,虽然不符合 W3C 标准。

  另针对 Windows Media Player ActiveX 控件。在 IE(包括马甲)第一次在网页上读到含有媒体装载的 embed 或 object 元素时,会给 IE 注册相应的加载项,虽然注册的名称不同,但是文件都指向 wmp.dll 或 wmpdxm.dll。含有有效 clsid 的 object 元素将注册名称为 Windows Media Player 的加载项;embed 元素则会根据文件 MIME 注册成对应名称的加载项(比如 wma 文件会注册 AUDIO__X_MS_WMA Moniker Class,wmv 文件会注册 VIDEO__X_MS_WMV Moniker Class,实际上这些 class 是原本就存在的,只是需要创建 MIME - CLSID 关联并链入 iexplore)。当禁用已经生成的加载项,或者加载项注册表被破坏时,其对应的 HTML 标签将失去作用。