innerHTML 将 CDATA 转换为注释

2024-04-12

我正在尝试使用 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 逐字插入到文档中吗?


document.createCDATASection https://developer.mozilla.org/en/DOM/document.createCDATASection应该这样做,但你的问题的真正答案是,虽然 HTML 5 确实有CDATA 部分 http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#cdata-sections对它们的跨浏览器支持相当不稳定。

EDIT

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

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

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;
        });
}

Given

<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: <><]]>

becomes

<script>/*<![CDATA[*/foo=bar<baz&amp;//]]></script>fish: &lt;&gt;&lt;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

innerHTML 将 CDATA 转换为注释 的相关文章

随机推荐