我应该使用“]]>”或“//]]>”将CDATA部分关闭为xHTML

时间:2010-03-03 21:43:15

标签: javascript html css xhtml cdata

我想在不转义特殊字符的情况下将脚本或CSS内联到XHTML中。

我可以使用CDATA标记的部分来做到这一点。

根据http://www.w3.org/TR/xhtml1/#h-4.8,CDATA部分可以定义为:

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

然后,根据http://www.w3schools.com/TAGS/tag_script.asp,CDATA看起来像:

   <script type="text/javascript"><![CDATA[
     // some code
   //]]></script>

关闭CDATA部分的哪种方法更好? ]]>//]]>

4 个答案:

答案 0 :(得分:33)

  

根据www.w3.org/TR/xhtml1/#h-4.8,CDATA部分可以定义为:[no //]

呀。在XHTML中,他们可以。正确的XHTML,由XML解析器读取,例如当您将application/xhtml+xml提供给非IE的Web浏览器时。

但可能您实际上是text/html,这意味着您的浏览器不是该部分中引用的“XML处理器”。它是遗留HTML4解析器,因此您必须遵守appendix C guidelines并避免使用在HTML4中不起作用的任何XML功能。

特别是,<![CDATA[]]>块中的字符串<script><style>对于HTML4解析器并不特殊,因为在HTML4中这两个元素是'CDATA标记不适用的元素(除了</ ETAGO序列以结束元素本身)。因此,HTML4解析器会将这些字符串直接发送到CSS或JavaScript引擎。

因为<![CDATA[无效JS,所以会出现JavaScript语法错误。 (其他答案在这里是错误的:它不仅仅是非常旧的浏览器,而是所有HTML4浏览器,它们会在脚本中为未注释的CDATA部分提供错误。)

您使用///*评论标记来隐藏JavaScript或CSS引擎中的内容。所以:

<script type="text/javascript">//<![CDATA[
    alert('a&b');
//]]></script>

(注意前导//; W3Schools示例代码中省略了这一点,并使该示例代码完全不起作用。失败。不要相信W3Schools:它们与W3C及其材料无关经常是垃圾。)

HTML解析器将其读取为:

  • 开放标记script建立CDATA内容,直到下一个ETAGO
  • 文字//<![CDATA[\n alert('a&b');\n//]]>
  • ETAGO和close-tag script
  • - &GT;结果内容发送到JavaScript引擎://<![CDATA[\nalert('a&b');\n//]]>

但是通过XML解析器:

  • Open-tag script(没有特殊的解析含义)
  • 文字内容//
  • 打开CDATA部分,建立CDATA内容,直到下一个]]>序列
  • 文字\n alert('a&b');\n//
  • 关闭CDATA部分
  • 关闭代码script
  • - &GT;结果内容发送到JavaScript引擎://\nalert('a&b');\n//

虽然解析过程完全不同,但JS引擎在每种情况下都会得到相同的有效代码,这要归功于//,唯一的区别在于评论。

请注意,这是一个与老派截然不同的案例:

<script type="text/javascript"><!--
    alert('a&b');
//--></script>

用于隐藏脚本/样式内容,以便在不理解<script><style>标记的浏览器中将其写入页面。这不会生成JavaScript / CSS错误,因为hack被置于不同的级别:它是CSS和JavaScript语言自身的语法特性,<!--被定义为什么都没有,让这个黑客工作。

这些浏览器是古老的历史;你今天绝对不应该使用这种技术。特别是在XHTML中,因为XML解析器会引起你的注意,将整个脚本块转换为XML注释而不是可执行代码。

  

我想在不转义特殊字符的情况下将脚本或CSS内联到xHTML中。

避免这样做,你会更快乐。

确实需要<中的&<style>字符吗?不,几乎从不。你真的需要<script>吗?嗯......有时,是的,在这种情况下,评论的CDATA部分是可以接受的。

但说实话,XHTML兼容性指南C.4适用于HTML4,与XHTML1一样:任何非平凡的内容都应该是外部脚本,然后您不必担心这一点。

答案 1 :(得分:3)

取决于浏览器。尽管有些人认为,w3schools与W3C没有关系,所以他们的建议是不加考虑。

现代浏览器应该能够识别CDATA部分。 MSIE OTOH没有,但是没关系,因为它根本不支持XHTML(你不是为了MSIE兼容性而发送XHTML内容作为text / html,是吗?那么使用XHTML没什么意义首先)。

问题是,不完全理解XHTML的浏览器会将CDATA指令视为常规文本。

tl; dr:完全向后兼容的解决方案将是:

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

这只是令人厌恶的。如果你想要保持向后兼容性或坚持使用HTML,直到你能够忽略MSIE 8(这需要人们多少年来回避MSIE 6,可能是在2020年左右),要么将JS放在JS文件中。

只有不了解脚本标记的浏览器才需要HTML注释(<!-- -->)。对于不了解CDATA部分的浏览器(即非MSHT的非XHTML浏览器),需要使用双斜杠。 XHTML需要CDATA部分以避免格式错误的XML(例如,大于和小于比较,否则会破坏XML或需要转义,这也是浏览器问题)。

有关将XHTML作为text / html发送的问题的详细信息,请阅读:http://hixie.ch/advocacy/xhtml

编辑:为了纠正自己,根据Hixie的说法,向后支持的完整语法实际上就是这样:

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

谢谢,Alohci。

答案 2 :(得分:1)

我会在没有//的情况下这样做。这些都是某些浏览器(谁将保持无名)必须被“愚弄”接受脚本标签中的右括号的日子。

答案 3 :(得分:0)

如果您担心有人使用的是一个根本不了解XHTML的旧浏览器,您可以在CDATA标记之前添加注释。但是,您必须在开始标记之前添加注释,以防止它导致语法错误:

<script type="text/javascript">
//<![CDATA[
  // some code
//]]>
</script>