innerHTML将CDATA转换为注释

问题描述 投票:5回答:7

[我正在尝试使用javascript将一些HTML插入页面,并且我插入的HTML包含CDATA块。

[我发现在Firefox和Chrome中,CDATA正在转换为注释。

HTML不在我的控制之下,所以很难避免使用CDATA。

以下测试用例,当页面上有一个id为“ test”的div时:

document.getElementById('test').innerHTML = '<![CDATA[foo]]> bar'

导致以下HTML被附加到'test'div:

<!--[CDATA[foo]]--> bar

有什么方法可以使用javascript逐字插入包含CDATA的HTML到文档中?

javascript html dom cdata
7个回答
4
投票

[document.createCDATASection应该这样做,但是您的问题的真正答案是,尽管HTML 5确实对它们具有document.createCDATASection跨浏览器支持,但还是很参差不齐。

编辑

CDATA部分只是不在HTML 4定义中,所以大多数浏览器无法识别它们。

但是它不需要完整的DOM解析器。这是一个可以解决此问题的简单词汇解决方案。

CDATA sections

给出

function htmlWithCDATASectionsToHtmlWithout(html) {
    var ATTRS = "(?:[^>\"\']|\"[^\"]*\"|\'[^\']*\')*",
        // names of tags with RCDATA or CDATA content.
        SCRIPT = "[sS][cC][rR][iI][pP][tT]",
        STYLE = "[sS][tT][yY][lL][eE]",
        TEXTAREA = "[tT][eE][xX][tT][aA][rR][eE][aA]",
        TITLE = "[tT][iI][tT][lL][eE]",
        XMP = "[xX][mM][pP]",
        SPECIAL_TAG_NAME = [SCRIPT, STYLE, TEXTAREA, TITLE, XMP].join("|"),
        ANY = "[\\s\\S]*?",
        AMP = /&/g,
        LT = /</g,
        GT = />/g;
    return html.replace(new RegExp(
        // Entities and text
        "[^<]+" +
        // Comment
        "|<!--"+ANY+"-->" +
        // Regular tag
        "|<\/?(?!"+SPECIAL_TAG_NAME+")[a-zA-Z]"+ATTRS+">" +
        // Special tags
        "|<\/?"+SCRIPT  +"\\b"+ATTRS+">"+ANY+"<\/"+SCRIPT  +"\\s*>" +
        "|<\/?"+STYLE   +"\\b"+ATTRS+">"+ANY+"<\/"+STYLE   +"\\s*>" +
        "|<\/?"+TEXTAREA+"\\b"+ATTRS+">"+ANY+"<\/"+TEXTAREA+"\\s*>" +
        "|<\/?"+TITLE   +"\\b"+ATTRS+">"+ANY+"<\/"+TITLE   +"\\s*>" +
        "|<\/?"+XMP     +"\\b"+ATTRS+">"+ANY+"<\/"+XMP     +"\\s*>" +
        // CDATA section.  Content in capturing group 1.
        "|<!\\[CDATA\\[("+ANY+")\\]\\]>" +
        // A loose less-than
        "|<", "g"),

        function (token, cdataContent) {
          return "string" === typeof cdataContent
              ? cdataContent.replace(AMP, "&amp;").replace(LT, "&lt;")
                .replace(GT, "&gt;")
              : token === "<"
              ? "&lt;"  // Normalize loose less-thans.
              : token;
        });
}

它产生

<b>foo</b><![CDATA[<i>bar</i>]]>

并且给出的内容看起来像<b>foo</b>&lt;i&gt;bar&lt;/i&gt; 内的CDATA部分或其他特殊标记或注释,它正确地不符合要求:

script

成为

<script>/*<![CDATA[*/foo=bar<baz&amp;//]]></script><![CDATA[fish: <><]]>

2
投票

您可以尝试使用<script>/*<![CDATA[*/foo=bar<baz&amp;//]]></script>fish: &lt;&gt;&lt; 代替innerText


2
投票

我只是使用正则表达式剥离CDATA标记,如下所示:

innerHTML

哪个会导致“测试”具有:

document.getElementById('test').innerHTML = '<![CDATA[foo]]> bar'.replace(/<!\[CDATA\[(.*)\]\]>/g, "$1")

这样,就可以保留CDATA节的内容,而不必担心其中的任何内容都会被注释掉。不幸的是,这可能会破坏您的文档使用CDATA部分开头的所有条件。


1
投票

转换和&符号,如下所示:

foo bar

1
投票

这是因为document.getElementById('test').innerHTML = '&lt;![CDATA[foo]]&gt bar' CDATA<>&lt;)转换为其html实体。尝试将实体转换回&gt;<

您可以阅读有关它的更多信息>


0
投票

如果将页面设为XHTML而不是HTML,则CDATA的自动注释“功能”可能不会发生。您确实需要跳过XHTML所需的箍,例如DOCTYPE,以及其他任何东西。

似乎有点武断,任何依赖CDATA的应用程序都损坏了,恕我直言,但希望您能使其正常工作。


0
投票

[我在2020年仍然遇到此问题:-(与OP的细微差别是:我需要将XML(not html)注入到div中。不幸的是,应用@Mike Samuel的答案将初始here转换为<?xml ...我只需要在正则表达式中添加以下子句:&lt;?xml ...

XML的完整功能:

"|<\\?[xX][mM][lL]"+ANY+"\\?>"
© www.soinside.com 2019 - 2024. All rights reserved.