我应该在HTML5中使用<![CDATA[...]]>吗?

88

我相信 <![CDATA[...]]> 可以在XHTML5中使用,那么在HTML5中呢?

5个回答

62

CDATA结构实际上不是针对HTML的,而是针对XML的。

人们有时会在XHTML中的script标签内使用它们,因为这样就不需要转义<>&字符了。但在HTML中是不必要的,因为HTML中的script标签已经像CDATA部分一样解析了。

编辑:这里我们打开一个非常陈旧的争论(2002年),即是否像“应该”的那样将XHTML作为text/htmlapplication/xhtml+xml发送 :-)。


1
我正在发送HTML(而不是XHTML),我希望如此。谢谢您的回答 :) - Darryl Hein
我可以在pre标签内使用CDATA,这样我就不必修复所有的尖括号了吗? - gman
1
不精确。CDATA 既适用于 SGML,也适用于 XML 子集。因此,它适用于 HTML 和 XHTML。 - Johan Boulé
@gman 不,pre 元素并不特殊。 - Mr Lister
@JohanBoulé 这取决于你的意思。为了澄清,SGML可以标记元素以具有CDATA内容,而XML可以在源中使用 <![CDATA[ .. ]]> - Mr Lister
@MrLister 没错。我对答案没意见,但第一句话看起来不太对。“CDATA结构并不是为HTML而设计的。” CDATA 是随 SGML 一起出现的,而 HTML 就是 SGML,所以这句话在逻辑上不通。 - Johan Boulé

26

来自@pst链接的同一页

针对scriptstyle标签的特定元素解析XHTML-HTML兼容性指南:“以下带有转义字符的代码可以确保脚本和样式元素在XHTML和HTML中都能正常工作,包括旧版浏览器。”

最大向后兼容性:

<script type="text/javascript"><!--//--><![CDATA[//><!--
    ...
//--><!]]></script>

更简单的版本,不兼容“旧得多的浏览器”:

<script>//<![CDATA[
   ...
//]]></script>

所以,CDATA可以在HTML5中使用,并且在官方的XHTML-HTML兼容性指南中推荐使用。

对于polyglot HTML/XML/XHTML页面非常有用,这些页面在开发期间作为严格的application/xml XML提供,但在生产模式下作为text/html HTML5提供,以获得更好的跨浏览器兼容性。 Polyglot页面有其优点;我自己也用过它,因为调试XML/XHTML5要容易得多。例如,Google Chrome会为无效的XML/XHTML5(包括例如字符转义)抛出错误,而以HTML5格式提供的同一页面将“仅工作”,也称为“可能工作”。


12
如果你想支持一些20年前的浏览器,如NSCA Mosaic或Netscape 1,那么需要在脚本标签中添加注释。请注意,这些注释很重要。 - Antti Haapala -- Слава Україні

18

规范澄清了这个问题。script和style标签被视为“原始文本元素”。它们不需要或不允许使用CDATA。CDATA仅用于“外来内容”-即MathML和SVG。请注意,对于可以放入script标签的内容存在一些限制-基本上不能像pst在他的答案中提到的那样放入类似于var x = '</script>'这样的内容,因为它会关闭标签,需要拆分。 http://www.w3.org/TR/html5/syntax.html#cdata-rcdata-restrictions


11

HTML5支持的浏览器(包括大多数自2001年以来的旧浏览器)已经将<style><script>标签内的内容视为CDATA(字符数据)。这意味着对于过去20年中构建的大多数HTML浏览器,通常不需要在这些元素内添加CDATA标记,因为它们将解析它们之间添加CSS和JavaScript代码时可能出现的任何特殊字符。

然而...如果你想让你的HTML5页面与XHTML和XML浏览器和解析器兼容,你确实需要在<style><script> HTML5标签内添加CDATA块,因为它们需要CDATA标记。因此,我建议您在HTML5<style><script>标签中使用CDATA,但请继续阅读。如果你做得不对,你会破坏你的网站

注意:CDATA标记帮助XML解析器忽略那些在这些元素之间弹出的特殊字符,这些特殊字符是XML元素的一部分,因此会破坏标记(例如使用<>字符)。只有现代HTML解析器中的<style><script>具有此特殊功能。这仅仅意味着在HTML浏览器和解析器中,它们被设计为忽略那些奇怪的字符,或者更准确地说,不读取或解析它们作为标记的一部分。如果它们没有内置的CDATA属性,你的网页、样式和脚本可能会破裂!

XML和XHTML解析器将像处理所有HTML元素一样处理<style><script>标签的内容,即PCDATA(即普通的HTML元素),这意味着内容被解析为标记并在这些标签之间添加特殊字符时有可能破坏。你可以在这两个标签之间添加特殊的CDATA段来支持它。因为XML和XHTML解析器将内部所有元素都视为潜在的更多标记,添加CDATA可以防止某些字符被解释为XML或其他类型的字符引用。

问题是,大多数HTML4/HTML5浏览器和解析器不支持在这些标签之间添加额外的CDATA段,因此,如果你为XHTML/XML支持添加了它们,CDATA块就必须被注释掉。

另外,请注意,所有添加在这些标签内部的HTML注释(<!---->)都会被HTML解析器忽略,但会被XHTML实现,当添加时会针对XHTML注释掉CSS和JavaScript。过去很多人会在这些标签之间添加注释规则,以隐藏样式和脚本,以避免不能理解CSS或Javascript(1998年之前的旧浏览器)。但在XHTML中,这种策略失败了,需要额外的代码来支持。

那么,如何结合<style><script>标签中的所有内容,你需要关心吗?

我是一个纯粹主义

<style type="text/css">
    <!--/*--><![CDATA[/*><!--*/

    ...put your styles here

    /*]]>*/-->
</style>

脚本

<script type="text/javascript">
    <!--//--><![CDATA[//><!--

    ...put your scripts here

    //--><!]]>
</script>

附加说明

  • 这两个代码块不会改变现代HTML5浏览器中的任何内容。

  • 这两个代码块将使您的CSS和JavaScript在HTML5浏览器中正常工作,但会从不支持这些技术的非常旧的浏览器(2001年之前)中隐藏CSS和JavaScript。

  • XHTML浏览器现在会像以前一样解析您的CSS和JavaScript,但不允许像<>&这样的特殊字符被解释为标记或实体/转义字符,否则会生成解析错误。它们现在是CDATA

  • 您页面的XML解析器当然不会理解您的CSS和JavaScript,但会接受您添加的任何类型的文本,并且不会尝试将其解析为标记。它们现在是CDATA

例子如何工作

对于现代HTML5支持的浏览器,因为scriptstyle元素表现得像CDATA,所有标记都会被忽略并被视为字符。所以在scriptstyle标签中的注释标记<!---->被忽略。不知道脚本或CSS的旧浏览器(2001年之前)不会将scriptstyle元素视为支持CDATA的元素。它们将识别HTML注释标记,因此会注释掉它们之间的所有CSS和JavaScript。请注意,有些浏览器确实知道CSS和脚本,但也读取HTML注释,因此我们关闭第一个注释(<!--/*-->),然后它们被迫阅读<![CDATA[/*>块(用于XHTML和XML解析器),对于这些浏览器来说,它变成了一个未知的空元素,并被忽略。块中跟随的HTML注释是设计用来隐藏从那里到块结尾的所有CSS和脚本的。最后的<!]]>是另一个被忽略的空元素,用于关闭仍然读取它的未知CDATA标记。

对于XHTML,这些解析器将读取这些标记内的所有代码作为HTML。它们还需要在块中的所有CSS和JavaScript周围包装一个CDATA元素,以使它们像HTML5浏览器一样工作。它们还没有将这些元素内的内容读取为CDATA。XHTML解析器将读取HTML注释标记,但也知道CSS和JavaScript注释,因此会提前结束它们。然后读取<![CDATA[元素并开始CDTA块,因为它是XHTML W3C建议中已知的HTML元素。然后在块内包裹所有样式和脚本,直到]]>结束它,创建一个真正的CDATA包装器,现在可以正确地隐藏XML字符。块内的所有内容都像HTML5解析器现在一样被解释为普通的CSS和脚本,但对于XHTML解析器来说,不再识别其中的HTML标记。因为新旧XHTML浏览


1
很高兴在2021年2月28日之后找到了这个帖子,所以这个答案已经在那里了 - 感谢所有的细节! - toraritte

5

可能需要看一下:http://wiki.whatwg.org/wiki/HTML_vs._XHTML

<![CDATA[...]]>是一个虚假的注释。

在HTML中,<script>已经受到保护--这就是为什么有时必须将其写成a = "<" + "/script>",以避免使浏览器混淆。请注意,该代码在HTML中CDT之外是有效的。


3
我认为避免结束标记的最佳方法是"</script>"。我已经读到一些解析器只检查"</"而不是"</script>". - marcus
@marcus 你是正确的,</ 是这种情况下唯一的特殊符号。我的关于这个主题的更新答案也认同了你的看法,因为我的知识随着时间的推移而得到了更新;-) 我会进行更新。话虽如此,似乎将 </scr + ipt> 分开使用在常见情况下仍然有效,我不知道有哪个主流的浏览器不支持它... - user166390

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接