【问题标题】:Should I use "]]>" or "//]]>" for closing a CDATA section into xHTML我应该使用“]]>”还是“//]]>”将 CDATA 部分关闭到 xHTML
【发布时间】:2011-01-23 10:20:15
【问题描述】:

我想将脚本或 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 部分的哪种方法更好? ]]&gt;//]]&gt; ?

【问题讨论】:

  • 或者,只是为了外部化脚本。顺便说一句:有基于 XHTML 的 MVC 框架(因为它们使用 XML 工具来解析源代码/生成输出)。这是 XHTML 的唯一优点。

标签: javascript html css xhtml cdata


【解决方案1】:

根据 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 功能。

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

因为&lt;![CDATA[ 不是有效的JS,你会得到一个JavaScript 语法错误。 (这里的其他答案是错误的:它不仅仅是非常旧的浏览器,而是所有 HTML4 浏览器,这会给脚本中未注释的 CDATA 部分带来错误。)

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

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

(注意前面的//;这在 W3Schools 示例代码中被省略了,这使得该示例代码根本不起作用。失败。不要相信 W3Schools:它们与 W3C 无关,而且它们的材料通常是垃圾。)

HTML 解析器将其读取为:

  • 打开标签 script 建立 CDATA 内容直到下一个 ETGO
  • 文字//&lt;![CDATA[\n alert('a&amp;b');\n//]]&gt;
  • ETGO 和关闭标签script
  • -> 将结果内容发送到 JavaScript 引擎://&lt;![CDATA[\nalert('a&amp;b');\n//]]&gt;

但通过 XML 解析器为:

  • 打开标签script(无特殊解析含义)
  • 文字内容//
  • 打开 CDATA 部分,建立 CDATA 内容直到下一个 ]]&gt; 序列
  • 文字\n alert('a&amp;b');\n//
  • 关闭 CDATA 部分
  • 关闭标签script
  • -> 将结果内容发送到 JavaScript 引擎://\nalert('a&amp;b');\n//

虽然解析过程完全不同,但 JS 引擎在每种情况下都会得到相同的有效代码,因为有了//s,唯一的区别在于 cmets。

请注意,这与老式的情况截然不同:

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

这是为了隐藏脚本/样式内容,这样它就不会被写入不理解&lt;script&gt;&lt;style&gt; 标签的浏览器的页面上。这不会产生 JavaScript/CSS 错误,因为 hack 将其置于不同的级别:它是 CSS 和 JavaScript 语言的语法特性它们自己&lt;!-- 被定义为什么都不做,允许这个黑客工作。

那些浏览器是古老的历史;你今天绝对不应该使用这种技术。尤其是在 XHTML 中,XML 解析器会按照您的要求将整个脚本块转换为 XML 注释而不是可执行代码。

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

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

真的需要&lt;style&gt; 中的&lt;&amp; 字符吗?不,几乎从来没有。你真的需要他们&lt;script&gt;吗?嗯...有时,是的,在这种情况下,commented-CDATA-section 是可以接受的。

但老实说,XHT​​ML 兼容性指南 C.4 对 HTML4 和对 XHTML1 一样适用:任何重要的东西都应该是外部脚本,然后您就不必担心这些了。

【讨论】:

  • “避免这样做,你会更快乐。”借调。
  • @Colonel Sponsz 当我开始学习编码时,我使用 W3schools 有一段时间了,我没有遇到任何问题。还有,w3fools 哪里说 w3schools 不好?
【解决方案2】:

取决于浏览器。尽管有些人认为,w3schools 与 W3C 无关,所以他们的建议是持保留态度。

现代浏览器应该能够识别 CDATA 部分。 MSIE OTOH 没有,但没关系,因为它根本不支持 XHTML(您不会将 XHTML 内容作为文本/html 发送以与 MSIE 兼容,是吗?那么使用 XHTML 没有多大意义首先)。

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

tl;dr:完全向后兼容的解决方案类似于:

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

这只是令人反感。如果您想保持向后兼容性,请将您的 JS 粘贴到 JS 文件中,或者坚持使用 HTML,直到您可以忽略 MSIE 8(根据人们避开 MSIE 6 的时间,可能在 2020 年左右)。

HTML 注释 (&lt;!-- --&gt;) 只有不理解脚本标签的浏览器才需要。不理解 CDATA 部分的浏览器(即 MSIE 等非 XHTML 浏览器)需要双斜杠。 XHTML 需要 CDATA 部分以避免格式错误的 XML(例如,大于和小于比较会破坏 XML 或需要转义,这又是一个浏览器问题)。

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

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

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

谢谢,Alohci。

【讨论】:

  • 鉴于您提到 Hixie 的文章,我以为您会引用他在其中提供的咒语,这比您的回答要复杂一些。
  • 该咒语用于支持 HTML4 和 XHTML1 以及不理解 &lt;script&gt;&lt;style&gt; 元素的古老的 pre-HTML3.2 浏览器。没有现成的 pre-HTML3.2 浏览器,在我想出它的时候也没有 (doxdesk.com/personal/posts/wd/20010911-cdata.html)。它不应该被使用。
  • 没错,但重点仍然存在。如果您担心转义 cdata 部分,因为您将 XHTML 作为 HTML 发送到将其解析为 tagoup 的浏览器,您做错了。如果您打算使用 XHTML,请不要将其作为 text/html 发送。如果您使用的是 HTML,请不要将 CDATA 部分放入其中。除此之外,我的建议仍然有效:如果您想确保没有浏览器绊倒它,请将您的脚本置于 HTML 之外。
  • 六年后回到这个话题,我可能应该补充一点,除非您真正使用的是 XHTML(您可能不是)而不是 HTML,否则您根本不应该使用 CDATA 部分。检查您是否使用 XHTML 的最佳方法是添加格式错误的 XML(例如,缺少结束标记)。如果浏览器不拒绝呈现它,它实际上将其视为 HTML,而您的 XHTML 只是毫无意义的标签汤。 XHTML 在现代网络上已经死了。 HTML 赢了。
【解决方案3】:

我会在没有//的情况下这样做。这些是对某些浏览器(将保持无名)不得不“愚弄”以接受脚本标签中的右括号的日子的回归。

【讨论】:

  • 不,这与 &lt;!-- ... --&gt; 的旧问题完全不同(这确实已过时)。 HTML4 中脚本元素内的一个朴素的&lt;![CDATA 不会被忽略,浏览器 绊倒它。试试看 — 你会得到一个 JavaScript 错误。
【解决方案4】:

如果您担心有人正在使用完全不了解 XHTML 的非常旧的浏览器,您可以将 cmets 放在 CDATA 标记之前。但是你必须在起始标记之前添加注释,以防止它导致语法错误:

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

【讨论】:

    猜你喜欢
    • 2010-12-31
    • 2010-11-26
    • 2012-06-20
    • 2013-05-23
    • 2013-02-05
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多