浏览器使用 MIME 类型来确定如何处理页(或其他资源)。例如,如果浏览器从 Web 服务器获得一个具有可识别图像 MIME 类型的文件,则浏览器尝试将该文件解释并呈现为图像。如果浏览器获得一个具有 application/msword MIME 类型的文件,则该浏览器可能自动打开 Microsoft Word 以显示该文档(这里的确切行为取决于浏览器及其配置方式)。
W3C 为 XHTML 文档引入了一个 MIME 类型。这一新的 MIME 类型是 application/xhtml+xml。W3C 建议您在提供 XHTML 文档时使用 application/xhtml+xml MIME 类型,因为 XHTML 页应该以比旧式 HTML 页更严格的方式进行解释。
通过在页指令中包含 ContentType 属性,为 ASP.NET 页分配特定的 MIME 类型。例如,在 ASP.NET 页的顶部包含以下指令会导致为该页分配 application/xhtml+xml 类型。
<%@ ContentType="application/xhtml+xml" %>
W3C 的推荐标准有一个突出问题:并非所有浏览器都能识别 application/xhtml+xml。特别需要指出的是,Internet Explorer(有史以来最为流行的 Web 浏览器)不能识别 application/xhtml+xml MIME 类型。因此,使用推荐的 application/xhtml+xml MIME 类型提供 XHTML 页不是一个可行的选择。
有三种解决该问题的方式。可以使用 text/html MIME 类型来提供 XHTML 页,或者使用 application/xml(或 text/xml)MIME 类型来提供 XHTML 页,也可以使用内容协商方式。让我们对上述每个选择进行探讨。
第一个选择 — 以 text/html 类型提供页 — 是最容易的选择。默认情况下,ASP.NET 页被分配为该 MIME 类型。更好的做法是,按照 W3C 的建议,在向现有的 HTML 浏览器提供页时使用这一选择(请参阅 http://www.w3.org/TR/xhtml-media-types/)。如果创建的是 XHTML 1.0 Transitional 页,并且 Web 应用程序的主要受众使用不能理解 application/xhtml+xml MIME 类型的浏览器,那么以 text/html 类型提供页似乎十分明智。毕竟,引入 XHTML 1.0 Transitional 标准的目的是使开发人员能够更为容易地将现有的 HTML 页迁移到 XHTML。
这一主张是有争议的。例如,Ian Hickson 认为,绝不应该以 text/html 类型提供 XHTML 页,因为这样会导致随便的、不标准的 XHTML 页(请参阅 http://hixie.ch/advocacy/xhtml)。他建议作者们继续坚持使用 HTML 4.0,直到更多的浏览器完全支持 XHTML 标准为止。
第二个选择是使用 application/xml 或 text/xml MIME 类型,以 XML 类型提供 XHTML 页。在向 Internet Explorer 提供 XML 文档时,该文档会作为 XML 文档进行分析并呈现到浏览器中。(该文档由 document.XMLDocument 对象公开的 XML DOM 表示。)
以 XML 类型提供 XHTML 文档的优点是,XHTML 文档具有的任何问题都会被 Internet Explorer 的 XML 分析器捕获。例如,如果文档包含重叠标记,或者如果没有将属性的值包装到引号内,则不会呈现该文档,并且会显示错误信息(参见图 4)。XHTML 纯粹主义者认为该行为是一件好事,因为它可以防止您编写格式错误的 XHTML。
图 4. 在 Internet Explorer 中显示 XML
该方法的问题是:默认情况下,Internet Explorer 呈现 XML 文档的源代码。因此,如果以 XML 类型提供 XHTML 文档,则 Web 站点访问者将看到 XHTML 文档的源代码,而不是预期的呈现输出。W3C 推荐了一个用来解决该问题的“窍门”(请参阅 http://www.w3.org/MarkUp/2004/xhtml-faq#ie):如果通过使用 XSLT 转换将 XHTML 文档转换为 HTML,那么文档将分析为 XML 并显示为 HTML。
例如,清单 1 中的 ASP.NET 页将以 XML 文档的形式提供,但被转换为 HTML 文档。结果页会正确地显示在 Internet Explorer、Opera 和 Firefox 中。
清单 1. XMLPage.aspx
<%@ Page Language="VB" ContentType="text/xml" %>
<?xml-stylesheet type="text/xsl" href="copy.xsl"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>My Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtFirstName" runat="server" />
</div>
</form>
</body>
</html>
<?xml-stylesheet type="text/xsl" href="copy.xsl"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>My Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtFirstName" runat="server" />
</div>
</form>
</body>
</html>
页指令会导致该页以 text/xml 类型呈现。清单中的第二行引用了一个名为 copy.xsl 的 XSLT 样式表,它会对当前文档执行标识转换。换句话说,除了将原始XML 文档中的所有元素复制到新的 HTML 文档中以外,它根本没有做任何事情。copy.xsl 的源代码包含在清单 2 中。
清单 2. Copy.xsl
<stylesheet version="1.0"
xmlns="http://www.w3.org/1999/XSL/Transform">
<template match="/">
<copy-of select="."/>
</template>
</stylesheet>
xmlns="http://www.w3.org/1999/XSL/Transform">
<template match="/">
<copy-of select="."/>
</template>
</stylesheet>
该解决方案是有效的,但它似乎不是很精彩。当分析 XML 文档时,的确获得了额外的验证步骤。但是,如果在 Visual Studio .NET 2005 或 Visual Web Developer 中生成 ASP.NET 页,那么开发环境会在“Source”视图中执行相同的验证。最后,Internet Explorer 将收到与向它发送 text/html 类型文档时相同的文档。
第三个选择 — 内容协商,将 W3C 推荐标准的精神与最大程度的浏览器兼容性最佳地组合在一起(请参阅 http://www.w3.org/2003/01/xhtml-mimetype/content-negotiation)。当使用内容协商时,会以不同的 MIME 类型向不同的浏览器提供 ASP.NET 页。如果浏览器声称它支持 XHTML,则向它提供 XHTML 类型的页;否则,以 text/html MIME 类型向该浏览器提供页。
清单 3 中的 Global.asax 包含向不同的浏览器提供不同 MIME 类型页所需的代码。如果将该文件添加到 Web 项目中,则每个 ASP.NET 页的 MIME 类型都会随着每个请求而修改。将页提供给 Firefox 或 Opera 时,该页以 application/xhtml+xml 类型提供。另一方面,Internet Explorer 6 会收到 text/html 页。
清单 3. Global.asax
<script runat="server">
Sub Application_PreSendRequestHeaders(ByVal s As Object, _
ByVal e As EventArgs)
If Array.IndexOf(Request.AcceptTypes, _
"application/xhtml+xml") > -1 Then
Response.ContentType = "application/xhtml+xml"
End If
End Sub
</script>
Sub Application_PreSendRequestHeaders(ByVal s As Object, _
ByVal e As EventArgs)
If Array.IndexOf(Request.AcceptTypes, _
"application/xhtml+xml") > -1 Then
Response.ContentType = "application/xhtml+xml"
End If
End Sub
</script>
转自:http://www.flywe.net/article.asp?id=133
没有评论:
发表评论