React中dangerouslySetInnerHTML渲染CDATA内容变为注释的问题
解决React中dangerouslySetInnerHTML渲染CDATA内容变成注释的问题
嘿,我来帮你搞定这个头疼的问题!你遇到的情况其实是浏览器本身的HTML解析规则导致的——CDATA是XML里的语法,HTML并不原生支持它,所以当浏览器看到<![CDATA[...]]>的时候,会自动把它当作注释处理,这就是为什么你在DOM里看到的是<!--[CDATA[Where is my text?]]-->。
下面给你两种可行的解决方案,根据你的需求选就行:
方案1:移除CDATA标签(推荐,适合不需要显示CDATA字面的场景)
因为你用了<pre>标签,它本身就会保留文本的原始格式,不需要CDATA来保护特殊字符。直接把CDATA的前后标签去掉,只保留里面的内容就好:
const HTML_OK = '<pre>My text looks good</pre>' const HTML_CDATA = '<pre><![CDATA[Where is my text?]]></pre>' // 定义处理函数:移除CDATA的前后标记 const stripCDATA = (htmlStr) => { return htmlStr.replace(/<!\[CDATA\[|\]\]>/g, '') } class Hello extends React.Component { render() { // 根据传入的props选择要渲染的内容,处理CDATA const targetHTML = this.props.useCDATA ? stripCDATA(HTML_CDATA) : HTML_OK return <div dangerouslySetInnerHTML={{ __html: targetHTML }} /> } }
这样渲染后,<pre>里就会正常显示Where is my text?了。
方案2:转义CDATA标签(适合需要显示[CDATA[...]]字面的场景)
如果你就是要在页面上显示完整的[CDATA[Where is my text?]]这段文本,那需要把CDATA标签里的特殊字符转义,让浏览器把它当作普通文本解析,而不是XML语法:
const HTML_OK = '<pre>My text looks good</pre>' const HTML_CDATA = '<pre><![CDATA[Where is my text?]]></pre>' // 转义CDATA的特殊字符 const escapeCDATATags = (htmlStr) => { return htmlStr .replace(/<!\[CDATA\[/g, '<![CDATA[') .replace(/\]\]>/g, ']]>') } class Hello extends React.Component { render() { const targetHTML = this.props.useCDATA ? escapeCDATATags(HTML_CDATA) : HTML_OK return <div dangerouslySetInnerHTML={{ __html: targetHTML }} /> } }
转义后,浏览器会把<
