Netscape 插件
插件是扩展 Netscape 网络浏览器功能的强大机制。使用插件,浏览器可以显示在浏览器开发时甚至没有想到的格式的文件,例如嵌入在较大网页中的多媒体文件。这允许网页以最大的视觉冲击力进行设计。像任何强大的技术一样,插件也很容易被误解或误用。本文将探讨何时使用 Netscape 插件可能合适,解释如何安装和删除插件,建议在哪里找到有用的插件,并提供有关实现您自己的插件的见解。
将插件与辅助应用程序进行比较和对比可能很有用。插件和辅助应用程序共享许多功能,并且在许多情况下可以互换使用。辅助应用程序较旧,并且可能比插件更被用户所熟悉。Netscape 自其浏览器软件的 1.0 版本以来就支持辅助应用程序,但插件支持直到 2.0 版本(UNIX 的 3.0 版本)才出现。
辅助应用程序和插件都是 Web 浏览器使用的补充软件,用于处理特定的文件格式。辅助应用程序可以独立于 Web 浏览器运行。但是,插件集成到浏览器中,并且只能在浏览器内运行。潜在的辅助应用程序可能已安装在您的系统上。一些非常有用的辅助应用程序,例如 xv,甚至在 Web 浏览器普及之前就已开发出来。
辅助应用程序由于独立于浏览器,因此必须创建自己的窗口以用于用户界面。插件可以使用浏览器提供的窗口。由于它们共享浏览器窗口,因此它们可以用于显示嵌入在较大 HTML 文件中的文件。辅助应用程序无法显示嵌入的文件。插件可以在文件被浏览器下载时访问文件内容。此类插件称为“流式”插件。辅助应用程序仅在文件完全下载后才“启动”。
MIME(多用途 Internet 邮件扩展)协议,在 RFC-1521 中描述,允许应用程序在 Internet 上交换不同类型的文件。文本标头标识消息体的数据格式。Web 浏览器使用 MIME 信息在显示文件之前对其进行分类。例如,如果 MIME 标头指示正文类型为“image/gif”,则浏览器将消息正文显示为 GIF(图形交换格式)文件。如果没有可用的 MIME 标头,浏览器会根据文件的扩展名为文件分配 MIME 类型。一旦确定了文件的 MIME 类型,浏览器就会在其内部表中搜索分配给该 MIME 类型的插件或辅助应用程序。
作为网络冲浪者,您可能会遇到 HTML 页面,其中嵌入了其他文件。如果没有合适的插件,您的浏览器将无法显示嵌入的文件。网页设计师创建您无法在没有专用软件的情况下显示的页面可能看起来很不礼貌,但是这种行为有一些合理的理由。例如,某些非专有的 MIME 类型在 Internet 上常用,并且在 Mac OS 和 Windows 上的 Netscape 中受支持,但在 UNIX 上不受支持。UNIX 用户必须为这些 MIME 类型安装插件。此类文件的一个示例是 MIDI(乐器数字接口);这些文件通常嵌入在网页中以提供背景音乐。
作为网页设计师,您可能希望在您的网页上使用新开发的多媒体文件格式。当前的 MIME 类型可能开发时间太短,以至于现有浏览器不支持。MIME 协议旨在可扩展。第三方不断开发具有专门功能的新 MIME 类型。此类 MIME 类型的示例包括文档呈现 (application/pdf)、便携式图形 (image/png)、矢量图形 (application/shockwave-flash) 或流式音频 (audio/pn-realaudio-plugin)。通常,开发这些 MIME 类型是为了销售创作软件。礼貌的第三方为尽可能多的平台提供免费插件。不幸的是,UNIX 支持通常是第一个被牺牲的。
可能会很想发明新的 MIME 类型,而不是使用现有的功能等效的 MIME 类型,或者在您的网页上嵌入专门的文件类型,例如 Microsoft PowerPoint 文件。但是,您的查看者可能没有合适的插件,或者可能无法或不愿意找到并安装一个插件。您精心设计的网页在您期望看到炫丽图形的地方可能会出现暗淡的灰色矩形。通常,最好仅在您的网页上使用最流行的 Internet MIME 类型。如果只有使用更专业的 MIME 类型才能满足您的需求,则最好先检查插件的可用性,甚至自己提供必要的插件。
Netscape 插件有很多来源。Netscape 维护着一个按功能或平台组织的插件网站(请参阅资源 1 和 2)。Netscape 为其浏览器配备了一个名为“默认插件”的特殊插件,当遇到未注册的 MIME 类型时会调用该插件。经用户批准,默认插件将搜索 Netscape 网站以查找合适的插件。
Netscape 网站不是插件的唯一来源,尽管它可能是最方便的来源。Usenet 新闻组、WWW 搜索甚至口口相传等传统来源都可以找到有用的插件。
但是,请注意,下载插件时应采取与下载任何其他软件时相同的预防措施。尽管插件不是成熟的应用程序,但它们可能会造成同样多的损害,无论是有意还是无意。与辅助应用程序不同,插件可能会导致浏览器内存泄漏、变得无响应甚至核心转储。如果源代码可用,您可以先检查代码,然后再自行编译插件。否则,您将不得不信任插件的来源。仅仅因为插件已在 Netscape 的网页上注册并不意味着 Netscape 对插件的行为提供任何形式的保证。
插件是动态代码模块,是 Netscape 客户端运行的平台所固有的。例如,Windows 插件是 DLL,而 UNIX 插件是共享对象库。当 Netscape Navigator 启动时,它会检查某些目录树中的插件模块。目录树中的每个插件候选者都会被加载,使用插件 API(应用程序编程接口)确定其功能,然后卸载。内部表将 MIME 类型分配给特定的插件。稍后,如果浏览器遇到需要插件支持的 MIME 类型,则会重新加载插件并保持加载状态,直到页面关闭。可以使用“帮助/关于插件”菜单查看已注册插件的列表。删除插件就像删除共享库一样简单。
Netscape Communicator for UNIX 附带的 README 文件解释了生成插件列表的算法
if($NPX_PLUGIN_PATH environment variable is set)<\n> Look at $NPX_PLUGIN_PATH, where $NPX_PLUGIN_PATH is a colon-delimited list of directories. else Look at all the following directories in order, overriding previous entries in case of duplicates: /usr/local/lib/netscape/plugins $MOZILLA_HOME/plugins $HOME/.netscape/plugins
Netscape 3.0 的算法甚至更简单。仅检查目录 /usr/local/lib/netscape/plugins 和 $HOME/.netscape/plugins。
每个 MIME 类型只能分配一个插件或辅助应用程序。这些分配存储在文件 $HOME/.mime.types 和 $HOME/.mailcap 中,其他应用程序可以使用它们。对话窗口允许用户解决冲突。对于 Netscape 3.0,该对话框位于“选项/常规首选项”下拉菜单的“助手”选项卡下。对于 Netscape 4.0,该对话框可通过“编辑/首选项/导航器/应用程序”菜单选项获得。此菜单还允许用户将文件扩展名与 MIME 类型关联起来。通常,当插件分配给 MIME 类型时,插件会将文件扩展名与 MIME 类型关联起来。
您可能对一种很棒的新 Internet 文件格式有一个想法,但想知道如何让 Netscape 识别它。您可能是一位网络冲浪者,您最喜欢的网站使用 Netscape 或任何可用的插件无法识别的文件格式。或者,您可能只是想更多地了解您的 Web 浏览器的工作原理。在任何情况下,接下来的几节将简要介绍设计和实现您自己的插件的过程。
首先,提醒一下辅助应用程序。如果文件未嵌入在 HTML 文件中,则也可以使用辅助应用程序来显示它。辅助应用程序是使用传统方法开发的,不需要遵守任何特殊的 API,也不需要特殊的调试技术。即使您的最终目标是插件,首先实现辅助应用程序,然后将辅助应用程序转换为插件可能会更有效。
一旦您决定构建插件,您将需要下载 Netscape 的插件 SDK(软件开发工具包)(请参阅资源 3)。插件 SDK 包括文档、示例代码,甚至还有一个用 C 语言编写的模板插件,并附带 Makefile。SDK 文档包括插件 API 的完整参考手册,以及一些插件设计的一般指南。与其在此处重复这些信息,我将探讨如何最有效地使用 API。
Netscape SDK 旨在促进跨平台开发。SDK 允许开发人员为 UNIX、Windows 和 Mac OS 插件使用单个源代码树。但是,跨平台插件开发人员面临着巨大的障碍。必须考虑不同的 GUI 标准、OS 标准和设备接口。甚至插件文件格式也因平台而异。例如,Windows 插件的名称必须以“np”开头,并通过版本资源而不是 API 提供描述性信息。我将通过专注于仅 UNIX 的插件开发来回避棘手的跨平台开发问题。
插件 API 由两组函数组成。第一组,名称以“NPP_”开头,是插件必须实现的函数。这些函数将在浏览器下载文件时由浏览器调用。第二组,名称以“NPN_”开头,是插件可以要求浏览器提供的服务,例如分配和释放内存、读取和写入 URL、提供版本信息以及将消息写入浏览器状态字段。
有十几个以上的“NPP_”函数。实现如此庞大而复杂的函数集可能看起来很可怕。为了揭开 API 的神秘面纱,这些函数可以分为几个 सामान्य 类别。有一些函数允许插件描述其功能 (NPP_GetMIMEDescription, NPP_GetValue)、初始化和完成数据结构 (NPP_Initialize, NPP_Shutdown, NPP_New, NPP_Destroy)、写入图形区域 (NPP_SetWindow) 和接收数据 (NPP_NewStream, NPP_Write, NPP_WriteReady, NPP_StreamAsFile, NPP_DestroyStream)。还有一些函数允许插件启用 LiveConnect (NPP_GetJavaClass) 并向打印机描述其图形区域 (NPP_Print)。
UNIX 插件必须实现 NPP_GetMIMEDescription。此函数返回以分号分隔的 MIME 描述列表。每个 MIME 描述都包括 MIME 类型、与该 MIME 类型关联的文件扩展名以及 MIME 类型的简要描述。NPP_GetValue 返回插件的名称以及插件的详细描述。
NPP_Initialize 和 NPP_Shutdown 分别在插件加载后和插件卸载前立即调用。这些函数使插件有机会分配和初始化全局数据结构,然后在不再需要时释放任何已分配的资源。
NPP_New 和 NPP_Destroy 被调用以创建或销毁插件播放器的特定实例。单个 HTML 页面上可能有多个具有相同 MIME 类型的嵌入文件。插件可能需要为每个实例维护单独的数据结构。创建插件实例时,浏览器会提供环境信息,例如插件是嵌入式还是整页,以及 HTML <EMBED> 标记中是否有任何特殊指令。但是,浏览器只有在成功创建实例后才会向插件实例提供图形区域或文件内容。
NPP_SetWindow 为插件提供了一个绘图的图形区域。UNIX 插件配备了一个 Motif Drawing Area 小部件。插件可以使用 X Window System 函数直接在图形区域中绘图,或者它可以创建新的小部件,使用 Drawing Area 小部件作为父级。请注意,由于 X 的两阶段小部件删除方案,插件不得与任何小部件库链接。否则,X 可能会在插件(和小部件库)卸载后尝试执行第二阶段删除,从而导致核心转储。插件必须仅使用已链接到浏览器的小部件类。对于 Netscape,这意味着 Motif 小部件。
浏览器使用函数 NPP_NewStream、NPP_Write、NPP_WriteReady、NPP_StreamAsFile 和 NPP_DestroyStream 与插件协商数据传输机制。插件可以选择零星地接收数据,或者插件可以要求浏览器在交付数据之前将所有数据收集到一个文件中。如果数据是零星到达的,则插件可以设置从浏览器传输数据的大小和速率的上限。
函数 NPP_GetJavaClass 允许插件启用 LiveConnect。LiveConnect 是一种插件与 Java 和 JavaScript 接口的技术。LiveConnect 允许 JavaScript 控制插件的执行。LiveConnect 需要加载和执行一个特殊的 Java 类。对于许多插件来说,这可能是不必要的开销。
函数 NPP_Print 允许插件以平台特定的方式向打印机描述自身。对于 UNIX,这意味着将 PostScript 写入文件。整页插件实例可以选择是处理打印的所有方面,还是让浏览器处理大多数方面。嵌入式插件实例没有选择。浏览器将询问用户有关打印目标、页面大小和方向等信息。然后,浏览器将打开一个文件并开始写入自己的 PostScript。当遇到插件实例时,将调用函数 NPP_Print。浏览器传入参数,提醒插件实例其在页面上的位置,并为插件实例提供 FILE 指针以添加其 PostScript。当 NPP_Print 返回时,浏览器会继续向文件中添加 PostScript,然后关闭文件并将其发送到打印目标。
如果插件未添加任何 PostScript,则在打印页面上插件的位置将出现空白区域。显示静态图形的插件可能应该实现此 NPP_Print。显示动画或播放声音的插件可以选择不实现 NPP_Print。当用户选择“文件/打印”或“文件/另存为”菜单选项,然后选择 PostScript 作为输出格式时,将调用此函数。不用说,正确实现此功能并非易事。即使是 Adobe 的 PDF 插件也包含一个缺陷,该缺陷在使用“文件/另存为”菜单选项时会导致核心转储。最好省略此功能,而不是实现得很差。
SDK 文档建议不要“阻止”任何 API 调用。在 API 调用执行时,浏览器将不会响应用户输入。因此,这些函数应在合理的时间段内完成。如果插件需要执行耗时的处理,则可以使用多种技术。要使用的最佳技术取决于许多因素,包括插件的性质以及个人偏好。
一种流行的技术是让插件创建一个完全独立的“伴随进程”。此解决方案可能非常可靠。伴随进程中的灾难性故障可能不会影响浏览器。但是,可能需要复杂的进程间通信机制来提供浏览器和伴随进程之间的同步。如果处理仅与浏览器松散连接,则此技术最合适。这也是将辅助应用程序转换为插件的最简单技术。
或者,插件可以使用浏览器中的时间片来完成其处理。插件可以使用 NPP_WriteReady 函数来限制来自浏览器的数据传输速率。在数据速率受限的情况下,插件可以在 NPP_Write 函数中执行处理,而不会降低浏览器性能。例如,流式视频插件可能会将数据传输速率限制为帧速率。每次浏览器调用 NPP_Write 函数时,插件只需处理一帧的数据,然后将控制权返回给浏览器。此技术最适合流式插件。
X 事件处理循环也可以提供处理时间片。X 事件处理循环的作用很像协作式多任务操作系统中的调度程序。它可以被命令在空闲时间或在特定时间间隔后分别通过 XtAppAddWorkProc 和 XtAppAddTimeOut 函数执行小的处理任务。此技术最适合具有交互式图形的插件,尤其是动画。
最后,插件可以在进程中创建一个单独的异步线程。线程编程可能很困难。许多 UNIX 库,尤其是图形库,都不是线程安全的。插件设计人员必须小心避免重入问题。此技术应保留用于无法使用以前任何技术的情况。
插件可能很难调试。浏览器直到在执行插件函数之前才加载插件。这没有给调试器留下太多设置断点的机会。可能有必要求助于使用 printf。一种使用调试器的技术是在方便的位置插入人为延迟,例如在 NPP_Initialize 的开头。延迟可以给调试器时间“附加”到浏览器。一旦调试器附加,就可以在插件内设置断点。
Netscape 插件可以增强网络冲浪体验。毕竟,体验创意多媒体比看到暗淡的灰色矩形有趣得多。Linux 插件可用于许多常用的 MIME 类型;有些需要编译,另一些则作为共享库提供,从而简化了安装。为不受支持的 MIME 类型实现插件完全在经验丰富的 Linux 程序员的能力范围之内,并且可能很有趣。UNIX MIDI 插件 (UMP) 的源代码可在 UMP 下载页面上找到(请参阅资源 4)。此源代码可用作其他插件项目的起点。我略过了跨平台开发、LiveConnect 支持和打印问题。有关这些主题或任何插件主题的更多信息,请随时与我联系。
