使用正确的 MIME 类型提供 XHTML

Posted

技术标签:

【中文标题】使用正确的 MIME 类型提供 XHTML【英文标题】:Serving your XHTML with the correct MIME type 【发布时间】:2011-08-25 22:32:12 【问题描述】:

从我记事起,我就一直在努力以正确的方式做事。好吧,我认为无论如何都是正确的方式。

现在我觉得是时候一劳永逸地回答一些非常重要的问题了。

所有对 Xhtml 发誓的人迟早会偶然发现这句话:“除非您提供正确的 MIME 类型,否则您的文档将被解释为常规 HTML”

说什么?我创建了一个完美的 XHTML 文档,遵循所有的标准和东西。我做错了什么?我错过了什么?

据我了解,它大部分是服务器的事情,所以我当然也对此进行了调查,似乎 php 函数 header() 是问题的答案。

是的,那么一切都很好。不,实际上不是,因为无论我在网上搜索多少,我都无法找到有关如何解决问题的一致信息,当我确实找到远程相关的东西时,这全都与浏览器的可比性等有关。

尽量说清楚。

我并不关心浏览器的可计算性。 (反正现在不是)

如果我犯了错误,我真正想要的只是接收 XML 类型的史诗失败消息,当然还有关于我如何实际做到这一点的知识。

简而言之,我想放弃 SGML 方式并拥抱 XML 方式,并且我希望能够毫无疑问地说该文档是有效的 XML/XHTML 并被解释为这样.

我的想法是,我可以通过 PHP 脚本简单地要求有问题的 XHTML 文档,并使用适当的 MIME 类型发送它,但是由于网络上的信息相互冲突,它实际上是如何完成的仍然是个谜。

我确实希望有人能够提供我正在寻找的答案,最好是提供相关信息的链接来支持它。如果你能为我做到这一点,我将永远感激不尽。

最好的问候。

编辑: 我不能说我理解为什么或如何理解,但至少我找到了一种让它发挥应有作用的方法,只需添加: 到常规 xhtml 文档的顶部,当然将文件类型更改为 PHP 以使其实际运行脚本。

我很确定这不是故事的结局,但现在我很开心。

【问题讨论】:

(相关) What are the problems associated with serving pages with an xhtml content type (相关) XHTML still harmful? 我不确定这是否有问题。您说您不担心浏览器兼容性,但浏览器决定如何解析文档以及哪些 mime 类型会改变它解析文档的方式。此外,通常由您使用的 Web 服务器来确定数据的 mime 类型(除非您通过 PHP 手动设置标头)。 通过 PHP 设置标题正是我想要做的,如果这是正确的方法。我个人认为这个问题很清楚。我创建了一个 XHTML 站点,却发现它没有被各种浏览器这样对待。看起来这实际上并不是所讨论浏览器的缺陷,而是文档标题、内容类型、mime 类型,无论它被称为什么。那么我该如何解决呢? @Zacariaz 不,不是。无论请求什么,通过 header() 强制内容类型总是将内容作为 XHTML 提供。正确的方法是检查请求标头中的接受标头,然后查看资源是否可以像请求的那样表示(内容协商)。如果没有,服务器应该用一个错误的请求头来响应。 【参考方案1】:

如果您强制使用 /xhtml+xml 标头,那么 IE 将不再解释您的页面。这就是为什么没有人真正费心去做正确的事情。 (这也是我在另一个网站上这样做的原因。)

但是,可以让您的网络服务器处理正确 MIME 类型的发送。通常你可以让mod_negotiation 处理它。但是,这需要每个文档有两个版本:

index.en.html
index.en.xhtml

然后,如果请求 url/resource /index,它将自动确定适当的文档版本,并使用正确的媒体类型发送。但是,它并不真正了解序列化格式的类型差异,也不能设置优先级。并且一开始就保留两个具有相同内容的文件并不太合理。

因此,更简单的方法是使用 mod_rewrite 来处理 MIME 类型切换:

RewriteCond %HTTP_ACCEPT !application/xhtml\+xml
RewriteRule .+\.xhtml$ - [T=text/html]

这将为所有 .xhtml 文档发送已配置的标头,但如果浏览器不指示 XHTML 支持,则会覆盖该标头。这还不够完整,因为为避免代理问题,如果您手动进行任何类型的内容协商,您还需要设置 Vary: 标头。这需要 mod_header:

RewriteRule .+\.xhtml$ - [E=VARY_XHTML:1]
Header append Vary "Accept" env=VARY_XHTML

您可以使用 PHP 脚本包装器来做同样的事情,但是您会失去让服务器处理它的所有好处。无论哪种方式,这都需要相当多的努力,这就是为什么几乎没有人真正做到这一点的原因。但是如果你真的想要 XML 解析错误,这可能是一个半可行的选择。

【讨论】:

当然要先检查一下,才做出这么大胆的表态,所以回复晚了,不过IE9好像没有这个问题,懒得升级了,他们可能对我要说的话不感兴趣,所以问题解决了。不过,能够告知人们他们需要做什么才能查看我的网站会很好,但我认为这仍然是可能的。无论如何感谢您的回答。 当然 IE9 实际上并没有将其视为 XML/XHTML,但我可以接受。 @Zacariaz - 如果您使用 XML mime 类型,IE9 确实会将其视为 XML/XHTML。如果 XML 格式不正确,您将不会遇到黄屏死机,但这不是 XML 要求。唯一这样的要求是,如果发生格式正确错误,XML 解析器必须停止将输入流作为 XML 处理,而 IE9 会这样做 据我了解,XML 标准要求解析器失败并通知它是否验证为 XML。也许我错了。 @Zacariaz - 在解析器规范中要求它必须“通知”有点困难,因为不能保证有任何东西或任何人需要通知,也不存在任何这样做的方法.这当然被广泛认为是在浏览器中做的正确事情,但令人失望的是 IE9 没有这样做。【参考方案2】:

要让浏览器解析器使用 XML 解析器解析 XHTML,它必须使用 XML Mime Type

HTML5 将其定义为:

术语 XML MIME 类型用于 参考 MIME 类型 text/xml, application/xml 和任何 MIME 类型 其子类型以四个结尾 字符“+xml”。 [RFC3023]

最常见的这种 mime 类型是 application/xhtml+xml,但它远不是唯一可能的类型。

【讨论】:

有趣。所以通过使用例如text/xml 您还可以欺骗 IE 使其符合 XHTML 标准吗? (找到了一些 <?xml-stylesheet 解决方法) @mario - IE,9 之前的版本,只是不解释 XHTML,对此无能为力。但它确实有一个 XML 解析器,它将接受 XML 输入并将 xslt 样式表应用到它。我相信它所做的是获取 that 的输出,并将其重新解析为普通 HTML。 我就是这么想的。这样的XSL stylesheet 只是将任何 /xml 文档转换为 HTML。所以没有实际的 XHTML 解析规则,也没有 XML DOM。但至少可以实现 OP 想要的:在显示之前验证 xml 的正确性。

以上是关于使用正确的 MIME 类型提供 XHTML的主要内容,如果未能解决你的问题,请参考以下文章

哪些 MIME 类型用于 HTML/网页

PHP - 使用正确的 MIME 类型打开上传的 DOCX 文件

我能否可靠地找出正确的 mime 类型来提供不受信任的内容?

如何通过 Django 正确地为我的 React 生产构建提供服务。当前配置存在 MIME 类型问题

WOFF 字体的 Mime 类型?

在 php 中更改输出的 mime 类型