17

我想在不转义特殊字符的情况下将脚本或 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

4 回答 4

34

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

是的。在 XHTML 中,它们可以。正确的 XHTML,由 XML 解析器读取,例如当您application/xhtml+xml向非 IE 的 Web 浏览器提供服务时。

但可能您实际上是在充当text/html,这意味着您的浏览器不是该部分中提到的“XML 处理器”。它是一个遗留的 HTML4 解析器,因此您必须遵守附录 C 指南并避免任何在 HTML4 中不起作用的 XML 功能。

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

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

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

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

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

HTML 解析器将其读取为:

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

但是通过 XML 解析器:

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

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

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

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

这是为了隐藏脚本/样式内容,以便它不会在不理解<script><style>标记的浏览器中写入页面。这不会产生 JavaScript/CSS 错误,因为 hack 将其置于不同的级别:它是 CSS 和 JavaScript 语言本身的句法特征,<!--被定义为不执行任何操作,从而允许此 hack 工作。

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

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

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

真的需要 a 中的<and&字符<style>吗?不,几乎从来没有。你真的需要他们<script>吗?嗯...有时,是的,在这种情况下,注释 CDATA 部分是可以接受的。

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

于 2010-03-03T23:11:21.537 回答
3

取决于浏览器。尽管有些人认为,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 注释 ( )。不理解 CDATA 部分的浏览器(即 MSIE 等非 XHTML 浏览器)需要双斜杠。XHTML 需要 CDATA 部分来避免格式​​错误的 XML(例如,大于和小于比较会破坏 XML 或需要转义,这又是一个浏览器问题)。

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

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

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

谢谢,阿洛西。

于 2010-03-03T21:53:55.497 回答
1

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

于 2010-03-03T21:48:23.307 回答
0

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

<script type="text/javascript">
//<![CDATA[
  // some code
//]]>
</script>
于 2010-03-03T21:51:17.967 回答