[我正在尝试使用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
应该这样做,但是您的问题的真正答案是,尽管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, "&").replace(LT, "<")
.replace(GT, ">")
: token === "<"
? "<" // Normalize loose less-thans.
: token;
});
}
它产生
<b>foo</b><![CDATA[<i>bar</i>]]>
并且给出的内容看起来像<b>foo</b><i>bar</i>
内的CDATA部分或其他特殊标记或注释,它正确地不符合要求:
script
成为
<script>/*<![CDATA[*/foo=bar<baz&//]]></script><![CDATA[fish: <><]]>
您可以尝试使用<script>/*<![CDATA[*/foo=bar<baz&//]]></script>fish: <><
代替innerText
。
我只是使用正则表达式剥离CDATA标记,如下所示:
innerHTML
哪个会导致“测试”具有:
document.getElementById('test').innerHTML = '<![CDATA[foo]]> bar'.replace(/<!\[CDATA\[(.*)\]\]>/g, "$1")
这样,就可以保留CDATA节的内容,而不必担心其中的任何内容都会被注释掉。不幸的是,这可能会破坏您的文档使用CDATA部分开头的所有条件。
转换和&符号,如下所示:
foo bar
这是因为document.getElementById('test').innerHTML = '<![CDATA[foo]]> bar'
将CDATA
和<
(>
和<
)转换为其html实体。尝试将实体转换回>
和<
。
您可以阅读有关它的更多信息>
。
如果将页面设为XHTML而不是HTML,则CDATA的自动注释“功能”可能不会发生。您确实需要跳过XHTML所需的箍,例如DOCTYPE,以及其他任何东西。
似乎有点武断,任何依赖CDATA的应用程序都损坏了,恕我直言,但希望您能使其正常工作。
[我在2020年仍然遇到此问题:-(与OP的细微差别是:我需要将XML(not html)注入到div中。不幸的是,应用@Mike Samuel的答案将初始here转换为<?xml ...
我只需要在正则表达式中添加以下子句:<?xml ...
。
XML的完整功能:
"|<\\?[xX][mM][lL]"+ANY+"\\?>"