技巧: 配置 Apache 为 XHTML 发送正确的 MIME 类型

摘自: IBM developerWorks China  被阅读次数: 628


yangyi 于 2007-07-07 20:56:40 提供


级别: 中级

Elliotte Rusty Harold (elharo@metalab.unc.edu), 副教授, Polytechnic University

2007 年 6 月 18 日

本文将向您展示:如何配置 Apache 以便为支持可扩展超文本标记语言(Extensible Hypertext Markup Language,XHTML)的浏览器标记文档的媒体类型为 application/xhtml+xml,同时仍然向不支持该语言的浏览器(如 Microsoft® Internet Explorer®)发送 text/html。

当 Web 服务器向浏览器发送文档时,它会给文档加上一个响应报头作为前缀,如 清单 1 所示。此报头包含了用于告诉浏览器如何解释文档的元数据。元数据的一个最重要的部分是最后一行中的 Content-Type。它将告诉浏览器如何呈现内容。例如,浏览器用于显示 JPEG 和 GIF 的代码是不同的。最重要的是,很多浏览器用于显示 XHTML 和超文本标记语言(Hypertext Markup Language,HTML)的代码也是不同的。

清单 1. 一个典型的 HTTP 响应报头

                HTTP/1.1 200 OK
Date: Thu, 04 Jan 2007 19:39:13 GMT
Server: Apache/2
Last-Modified: Wed, 06 Sep 2006 11:19:37 GMT
ETag: "4dfce0-c4aa-26828440"
Accept-Ranges: bytes
Content-Length: 50346
Content-Style-Type: text/css
Content-Type: application/xhtml+xml

Web 服务器应该给 XHTML 文档加上媒体类型标记 application/xhtml+xml。识别此媒体类型的 Web 浏览器就会相应地将其以 strict 模式而不是 tag soup 模式运行。这使浏览器能更可靠地进行显示,对于级联样式表(Cascading Style Sheets,CSS)布局和基于文档的对象模型的 JavaScript ™ 程序,这一点尤为重要。事实上,在一些情况下同一文档能以两种不同的方式显示,取决于其处理模式是 tag soup 还是 strict。如果想要生成格式良好甚或是有效的 XHTML,则 strict 模式将会是您计划使用并希望使用的模式。

不支持 XHTML 的浏览器也能以 tag soup 模式处理格式良好的文档。结果并不完美,但可以满足一小部分使用很老的浏览器的用户需要。对于大部分使用不符合标准的 Internet Explorer 的用户来说,结果也还可以接受。但是,当前版本的 Internet Explorer(包括 6 和 7)无法识别 application/xhtml+xml 媒体类型。如果向 Internet Explorer 发送 application/xhtml+xml 文档,它将会反过来要求您保存文件,如 图 1 所示。


图 1. Internet Explorer 不知道如何处理 application/xhtml+xml
某些文件可能会损害您的计算机。如果下面的文件信息看起来可疑,或者您不完全信任其来源,请不要打开或保存此文件。文件名:a.xhtml

因此,处理 XHTML 时,要获得最大的兼容性,就需要向 Firefox、Safari、Opera 和其他符合标准的浏览器发送 application/xhtml+xml,而向 Internet Explorer 发送 text/html。在这两种情况下发送的是同一个文件。您只需在超文本传输协议(Hypertext Transfer Protocol,HTTP)的报头中更改文件的媒体类型标记即可。使用 Apache Web 服务器时,可在服务器配置文件或个人目录中的 .htaccess 文件中做此更改。

Apache 配置指令

根据默认,Apache 通过检查文件的扩展名来决定与每个文件一起发送的媒体类型。扩展名类型映射存储于 httpd/conf 目录(通常是类似 /usr/httpd/conf 或 /etc/httpd/conf 的目录)下的 mime.types 文件中。比如,清单 2 显示了 Apache 2.0 的 mime.types 文件的部分内容。

清单 2. Apache 的 mime.types

                # This file controls what Internet media types are sent to the client for
# given file extension(s).  Sending the correct media type to the client
# is important so they know how to handle the content of the file.
# Extra types can either be added here or by using an AddType directive
# in your config files. For more information about Internet media types,
# please read RFC 2045, 2046, 2047, 2048, and 2077.  The Internet media type
# registry is at <http://www.iana.org/assignments/media-types/>.

# MIME type                     Extensions
application/atom+xml            atom
application/mathematica
application/mathml+xml          mathml
application/msword              doc
application/octet-stream        bin dms lha lzh exe class so dll dmg
application/postscript          ai eps ps
application/rdf+xml             rdf
application/reginfo+xml
application/xhtml+xml           xhtml xht
application/xslt+xml            xslt
application/xml                 xml xsl
application/xml-dtd             dtd
application/xml-external-parsed-entity
application/zip                 zip
audio/mpeg                      mpga mp2 mp3
image/jpeg                      jpeg jpg jpe
image/naplps
image/png                       png
image/svg+xml                   svg
image/tiff                      tiff tif
text/html                       html htm
text/plain                      asc txt
text/sgml                       sgml sgm
text/xml
text/xml-external-parsed-entity
video/mpeg                      mpeg mpg mpe

一些更老的版本没有根据默认安装所有这些映射,并且可能事实上使用了一些十分有害的映射。尤其应该注意,对于原始 XML 文件使用 text/xml 而不是 application/xml 是一个常见的问题。

具有了这些默认的映射后,您所需要做的全部工作就是为 XHTML 文件加上 .xhtml 或 .xht 后缀,而不是 .html 后缀,之后,所有这类文件都将被作为 application/xhtml+xml 处理。这对于 Firefox、Opera 和 Safari 效果很好,但对于 Internet Explorer 却并非如此。您所需要的是一种方法,通过它可向 Internet Explorer 发送一种媒体类型而向所有其他浏览器发送另一种媒体类型。





回页首


浏览器嗅探

2007 年,可以放心假设所有非 Internet Explorer 的浏览器都能识别 application/xhtml+xml。(如果您确实希望支持很老的浏览器,则破解我下面提出的规则也很容易。)因此您就需要识别 Internet Explorer 的所有版本并将媒体类型更改为 text/html。幸运的是,Internet Explorer 在发送 HTTP 请求时可告知服务器浏览器的类型,如 清单 3 所示。

清单 3. Internet Explorer 的 HTTP 请求报头

                GET /test/a.xhtml HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, 
        application/msword, application/vnd.ms-powerpoint, */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)
Host: www.xom.nu
Connection: Keep-Alive

关键在于 User-Agent 字段。虽然由于传统原因 Internet Explorer 在开始时感觉像是 Netscape,但 MSIE 字符串可将其识别为 Internet Explorer。所有版本的 Internet Explorer 在 User-Agent 字段中都包含了此字符串,而所有其他现代的浏览器都不具备此特征。

您需要配置服务器以便查看报头中的 User-Agent 字段,并向 Internet Explorer 发送 text/html,向所有其他浏览器发送 application/xhtml+xml。mod-rewrite 模块并不局限于重写 URL。它还能根据 User-Agent 更改 HTTP 响应报头。清单 4 展示了配置文件中需要放入的代码。

清单 4. 向 Internet Explorer 发送 text.html

                RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} .*MSIE.*
RewriteCond %{REQUEST_URI} \.xhtml$
RewriteRule .* - [T=text/html]

第一行会打开重写引擎。

第二行的第一个重写条件表明:下面的规则仅适用于 HTTP 请求报头中的 user-agent 字符串包含子字符串 MSIE 的情形。正则表达式 .*MSIE.* 实现了此功能。

第三行的第二个重写条件表明:下面的规则仅适用于浏览器请求的文件具有 .xhtml 扩展名的情形。常规的 .html 文件被作为普通的 text/html 提供给所有浏览器。

最后一行是实际的重写规则。此规则有点不太常见,因为重写并未真正更改 URL 中的任何东西。接下来,匹配整个 URL (.*) 但接着将其替换成它自己 (-)。然而,最后的 [T=text/html] 字段会把 Content-Type 报头更改为 text/html。如果同时匹配上述两个条件,则使用此规则。反之则不然。

安装规则

根据服务器设置的不同,此代码可能位于以下几个位置之一:

  • 主 httpd.conf 文件
  • httpd.conf 文件中的 VirtualHost 部分或单独的虚拟主机配置文件
  • XHTML 文件所在目录中的 .htaccess 文件

这些指导说明在 Apache 1.3 和 2.0 中应该都有效。如果您在 .htaccess 文件中使用这些规则,则似乎没什么作用,这时,确保对目录做出了如下设置以允许在主 httpd.conf 文件中进行覆盖:

<Directory /var/www/foo>
  AllowOverride FileInfo
</Directory>

Lynx

如果可以的话,您应该多支持一个不能识别 application/xhtml+xml 的浏览器:Lynx。Lynx 是一种文本模式浏览器,主要由自动化脚本和处理 shell 的 UNIX® 爱好者使用。它的市场份额很小,但是其独特的功能使它具有了足够的重要性,颇值得我们关注,但前提是不给其他用户造成不便。

幸运的是,所有 Lynx 的 user-agent 字符串都以词 “Lynx” 开头,而其他的 user-agent 字符串都不包含该词。因此,为支持 Lynx,您所要做的全部工作就是将该字符串添加到重写条件正则表达式中,如 清单 5 所示:

清单 5. 向 Lynx 发送 text.html

                RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} ((.*MSIE.*)|(Lynx.*))
RewriteCond %{REQUEST_URI} \.xhtml$
RewriteRule .* - [T=text/html]

第二行中的新正则表达式匹配任何包含 MSIE 或以 Lynx 开头的字符串。如果发现另一个浏览器不能很好地处理 application/xhtml+xml,则可向其 user-agent 字符串中做类似的添加。

伪装成 Internet Explorer

一些更老版本的 Opera 和 Safari 通过在其 user-agent 字符串中包含 MSIE 将自己伪装成 Internet Explorer。但是您无需为此忧虑,原因如下:

  • 几乎已经没什么人使用那些版本了。
  • 与一些更新版本的 Safari 和 Opera 不同,那些较老的版本总的说来处理 text/html 比处理 application/xhtml+xml 的效果好。

要了解更精确的目标信息,请参阅 参考资料 中到 user-agent 字符串完整列表的链接和可供您参考的 application/xhtml+xml 浏览器支持。





回页首


结束语

分享这篇文章......

digg 将这篇文章提交到 Digg
del.icio.us 发布到 del.icio.us
Slashdot 提交到 Slashdot!

XHTML 是 Web 的未来。但是,像很多其他重要的技术一样,它的采用由于得不到 Microsoft 浏览器的有力支持而受到阻碍。如本文所展示的那样,没有理由等待 Microsoft。您可以轻松地向非 Microsoft 的浏览器提供 XHTML,同时仍然告诉 Internet Explorer 将它作为 tag soup 处理。现代浏览器的访客和页面作者将完全受益于 XHTML,而受 Internet Explorer 牵制的访客则仍然可获得大部分内容。适当地设置 Multipurpose Internet Mail Extensions(MIME)媒体类型并不是向旧的浏览器提供 XHTML 所能采用的惟一途径,但它却是往正确方向上迈出的一大步。



参考资料

学习

获得产品和技术
  • IBM 软件下载资源中心:使用 IBM 试用软件构建您的下一个开发项目,这些软件可直接从 developerWorks 下载。


讨论


关于作者

Photo of Elliot Rusty Harold

Elliotte Harold 出生在新奥尔良,现在他还定期回老家喝一碗美味的秋葵汤。但目前他和妻子 Beth、他们的狗 Shayna、猫 Charm 和 Marjorie 定居在布鲁克林附近的 Prospect Heights。他是 Polytechnic 大学的计算机科学副教授,讲授 Java 和面向对象编程。他的 Cafe au Lait Web 站点是 Internet 上最受欢迎的独立 Java 站点之一,子站点 Cafe con Leche 是最受欢迎的 XML 站点之一。他的著作包括 Effective XML Processing XML with Java Java Network Programming The XML 1.1 Bible 。他的最新著作是 Java I/O, 第二版。他目前从事 XOM API 处理 XML、Jaxen XPath 引擎和 Jester 测试覆盖工具的研究。




原文链接: http://www.ibm.com/developerworks/cn/xml/x-tipapachexhtml/index.html