WordPress何时在CDATA中包装内联脚本?

时间:2015-07-28 作者:m90

我正在调试我们的第三方脚本的一个问题,wordpress用户通过将脚本和html片段复制/粘贴到他们的帖子正文中来使用该脚本(当然是非真实世界的示例):

<script>
window.foobar = window.foobar || { hello: function(){ console.log(\'Hello World\'); } };
window.foobar.hello();
</script>
我注意到有些wordpress安装会将其包装在CDATA中,有些则不会(可能通过进行某种DOCTYPE检查-尽管我测试的所有主题都使用HTML5 DOCTYPE)。

然而,在CDATA中包装脚本时,用户会被以下错误所困扰:https://core.trac.wordpress.org/ticket/3670 (截止日期> 错误地替换为&gt;) 这会导致浏览器忽略脚本内容:

<script>// <![CDATA[  window.foobar = window.foobar || { hello: function(){ console.log(\'Hello World\'); } }; window.foobar.hello();  // ]]&gt;</script>
我自己没有太多的WP-Fu,而google只能让我按原样识别问题,所以我的问题是:WordPress究竟何时将内联脚本包装到CDATA部分?用户能否以某种方式阻止这种行为?用户是否可以在不修改WP-core的情况下解决上述bug?

1 个回复
SO网友:cjbj

Actually, it is not WordPress that is inserting the CDATA tags, but the visual editor, TinyMCE. Details of TinyMCE are offtopic here, but you can read a solution to this on Stackoverflow.

That said, stopping TinyMCE may not be the full solution you want. WordPress itself also has a function for adding CDATA tags, wxr_cdata, which is used when outputting a valid xml-file, for instance if you want to export the file of use the content in a rss-feed. Themes and/or plugins could decide to attach this filter to the content if they want the document to be valid xhtml.

This is where you then run into the bug, which was first documented twelve years ago and remains unsolved. It\'s about these three lines in the_content:

$content = apply_filters( \'the_content\', $content );
$content = str_replace( \']]>\', \']]&gt;\', $content );
echo $content;

As you can see, the str_replace is hardcoded, immediately followed by the echo. There\'s no way to intercept this replacement.

What you can do, however, if you control your theme, is buffer the_content and reverse the replacement. Like this:

ob_start();
the_content();
$content = ob_get_clean();
$content = str_replace( \']]&gt\', \']]>\', $content ); 
echo $content;
结束