在脚本标签中什么时候需要使用CDATA节?

967

CDATA标记在脚本标记中是否必要,如果必要,在什么情况下需要使用?

换句话说,什么时候以及在哪里需要这样做:

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

更好的选择是:

<script type="text/javascript">
...code...
</script>

21
现在XHTML基本上已经死亡,这个问题是否不再相关? - allyourcode
84
你怎么认为XHTML已经死了?是因为HTML5吗?实际上,XHTML5与HTML5并存 :) - Doktor J
4
据我所知,xHTML 的版本为 1,它的 HTML 等效版本为 4。xHTML 2.0 的努力集中在将 xform、xlink、time 和 svg 命名空间推入规范中,以改进 HTML 5 添加的相同功能 - xform / 输入验证、时间/动画、svg / canvas。但是,xHTML 2 规范的努力被重新聚焦于 HTML 5 的功能。这并不意味着 xHTML 2 被放弃或变得过时,但在不久的将来没有计划进行更新。 - Mihai Stancu
14
在Java Seam / JSF / Facelets的开发中,XHTML并没有消亡。 - JoJo
17
@Mihai Stancu,那并不完全正确。根据W3C,HTML5有一种XML语法:“可用于HTML5的另一种语法是XML。该语法与XHTML1文档和实现兼容。使用此语法的文档需要使用XML媒体类型进行服务,并且元素需要按照XML规范中制定的规则放置在http://www.w3.org/1999/xhtml名称空间中。” - BrainSlugs83
显示剩余6条评论
15个回答

604
如果您需要文档解析为XML(例如将XHTML页面解释为XML),并且想要能够编写字面意义上的i<10a && b而不是i&lt;10a &amp;&amp; b,则需要使用CDATA部分。因为XHTML会默认将JavaScript代码解析为已解析字符数据而不是字符数据。对于存储在外部源文件中的脚本没有问题,但对于任何内联XHTML中的JavaScript,您可能需要使用CDATA部分。
请注意,许多XHTML页面并不打算解析为XML,这种情况下这不会成为问题。
关于此主题的良好撰写,请参见https://web.archive.org/web/20140304083226/http://javascript.about.com/library/blxhtml.htm

52
不只是“验证”这么简单。大多数严格的XML解析器在遇到非法字符时将不会继续解析页面。这不仅仅是为了让W3C满意并获得绿色而不是红色的标记。 - Loren Segal
42
如果您避免使用&<字符,就不需要使用CDATA段落;它可以在HTML和XHTML中正常工作。您可以通过将所有重要的代码放入外部脚本,并仅使用内联脚本来初始化变量(如果需要,在字符串文字中转义&/<\x26/\x3C)来轻松实现这一点。 - bobince
24
HTML5的情况怎么样? - Mathew Attlee
5
@Mathew Attle - 这是个好问题。如果您在一个单独的主题线上提出这个问题,将会更容易引起关注。 - Alex KeySmith
3
@Loren: 那么这仍然完全与验证有关。用户代理拒绝无效XML的程度是不相关的。 - Lightness Races in Orbit
显示剩余7条评论

238

当浏览器将标记视为XML时:

<script>
<![CDATA[
    ...code...
]]>
</script>
当浏览器将标记视为HTML时:

When browsers treat the markup as HTML:

<script>
    ...code...
</script>
当浏览器将标记视为HTML并且您希望您的XHTML 1.0标记(例如)得到验证时。
<script>
//<![CDATA[
    ...code...
//]]>
</script>

15
出于代码安全性考虑,最好使用块注释 /* ... */ 包围你的 CDATA 部分,否则如果移除换行符,代码将会出错。 - BryanH
在第一部分中,“...作为XML”应该改为“...作为非解释文本”吗?在https://dev59.com/73E85IYBdhLWcg3wbS1h中,我们看到“...这些字符串包含的数据可能会被解释为XML标记,但不应该这样做。” - matt wilkie
@mattwilkie,我所说的“作为XML”是指“当浏览器使用其XML解析器(而不是HTML解析器)来解析标记时,因为文档是以基于XML的MIME类型发送的或包含标记的文件具有基于XML的文件扩展名”。 - Shadow2531

136

HTML

在HTML中,一旦遇到<script>标签,解析器会将其与</script>之间的所有内容都视为脚本的一部分。有些实现甚至不需要正确的闭合标签;它们会在"</"处停止脚本解释,这符合规范

更新: 在HTML5和当前的浏览器中,情况已经不再如此了。

所以,在HTML中,以下操作是不可能的

<script>
var x = '</script>';
alert(x)
</script>

CDATA部分完全没有影响。这就是为什么你需要编写:

var x = '<' + '/script>'; // or
var x = '<\/script>';

或类似的。

这同样适用于以text/html形式提供的XHTML文件。(由于IE不支持XML内容类型,因此这基本成立。)

XML

在XML中,应用不同的规则。请注意,(非IE)浏览器仅在XML内容类型下服务的XHTML文档中使用XML解析器。

对于XML解析器而言,script标记并不比其他标记更好。特别地,脚本节点可能包含由"<"触发的非文本子节点,并且"&"符号表示一个字符实体。

因此,在XHTML中,这是不可行的:

<script>
if (a<b && c<d) {
    alert('Hooray');
}
</script>

为了解决这个问题,您可以将整个脚本包装在一个 CDATA 区块中。这会告诉解析器:“在这个区块中不要将“<”和“&”视为控制字符”。为了防止 JavaScript 引擎解释 "<![CDATA[" 和 "]]>" 标记,您可以将它们包装在注释中。

如果您的脚本不包含任何 "<" 或 "&",则不需要 CDATA 区块。


2
“CDATA部分完全没有任何影响”这个说法在(拟议的)HTML5中并不正确,因为HTML5能识别该结构。http://www.w3.org/TR/html5/syntax.html#cdata-sections - danorton
3
有趣。我认为这是一种相当丑陋的混合。尽管如此,脚本内容仍然没有影响。 - user123444555621
2
不知道在脚本标签内任何</都是不好的。 - Salman A
3
@SalmanA 这是 HTML 的一种奇怪现象,官方称之为 ETAGO。了解更多信息:http://mathiasbynens.be/notes/etago。(虽然文章指出没有浏览器实现这个特性,但我相信它给我造成了一些麻烦。也许在其他工具中有所体现) - user123444555621
1
实际上,我遇到了验证问题-- <script>var b = "<b>bold</b>";</script> 无法通过验证,但是在阅读了您的答案并更改为 <script>var b = "<b>bold<\/b>";</script> 后,问题得到了解决。 - Salman A
显示剩余2条评论

32

基本上是允许编写既是XHTML又是HTML的文档。问题在于,在XHTML内部,XML解析器将解释脚本标记中的&、<、>字符并导致XML解析错误。因此,您可以使用实体编写JavaScript,例如:

if (a &gt; b) alert('hello world');

但这种方法并不实用。更大的问题是,如果您在HTML中阅读页面,标签 script 默认被视为CDATA,并且这样的JavaScript将无法运行。因此,如果您希望同一页面在使用XHTML和HTML解析器时都正常工作,您需要在XHTML中将 script 标签包含在CDATA元素中,但不要在HTML中这样做。

这个技巧将CDATA元素的开始标记标记为JavaScript注释;在HTML中,JavaScript解析器会忽略CDATA标记(它是一个注释)。在XHTML中,XML解析器(在JavaScript之前运行)会检测到它,并将其余部分视为CDATA直到CDATA结束。


24

这是一个与XML相关的技术。当您在JavaScript中使用像<>这样的符号来比较两个整数时,这需要像解析XML一样进行解析,因此它们会被标记为开始或结束标记。

CDATA表示以下行(直到]]>之前的所有内容)不是XML,因此不应该以那种方式进行解析。


18

在HTML4中不要使用CDATA,但在XHTML中应该使用CDATA,在XML中如果有未转义的符号像<和>则必须使用CDATA。


11
CDATA在HTML4中无效。简单来说,它不是语法的一部分。CDATA是XML的一种语法,而XHTML则是XML的子集。因此,它应该仅在XML(及其子集)内使用。另一方面,HTML不是XML。 - Loren Segal

17

在页面中嵌入JavaScript而非外部引用时,需要确保XHTML验证工作正常。

XHTML要求您的页面严格符合XML标记要求。由于JavaScript可能包含具有特殊含义的字符,因此必须将其包装在CDATA中,以确保验证不会将其标记为格式错误。

在Web上使用HTML页面时,您只需在标签之间包含所需的JavaScript。当您验证网页的HTML时,JavaScript内容被视为是CDATA(字符数据),因此被验证器忽略。如果您遵循更近期的XHTML标准设置Web页面,则情况并非如此。在XHTML中,脚本标记之间的代码被视为是PCDATA(解析字符数据),因此将被验证器处理。

因此,您不能仅仅在页面的脚本标记之间包含JavaScript,否则会“破坏”您的网页(至少在验证器的眼里是这样)。

您可以在此处了解更多关于CDATA的信息,以及了解更多关于XHTML的信息


11

CDATA 表示在其中的内容不是XML格式。

这里有一个关于wikipedia的解释。


9
当您需要严格遵守XHTML标准时,您需要使用CDATA,这样小于号和&符号就不会被标记为无效字符。

8
为了避免在XHTML验证期间出现XML错误。

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