PHP:使用DOM类构建<script>元素遇到的XHTML兼容问题
解决DOMDocument生成符合XHTML 1.0规范的
<script>元素问题 嘿,这个问题我太熟悉了!用DOMDocument生成XHTML时,<script>元素里的特殊字符(比如&&里的&)会被自动转义成&,既会导致脚本执行出错,也不符合XHTML 1.0附录C里兼容HTML的XHTML要求。
问题根源
你当前的代码会输出类似这样的内容:
<script>console.log(1 && 1);</script>
这是因为DOMDocument默认会把文本节点里的XML特殊字符自动转义,但XHTML规范里,<script>的内容应该被视为CDATA(字符数据)——解析器不应该把里面的&、<等字符当作标记处理。
正确解决方案
要生成符合规范的代码,你需要用createCDATASection()代替createTextNode(),同时别忘了给<script>加上type属性(XHTML要求必须声明):
$document = new \DOMDocument(); $element = $document->createElement('script'); // 用CDATA段存储脚本内容,避免特殊字符被转义 $script = $document->createCDATASection('console.log(1 && 1);'); $element->appendChild($script); // 添加XHTML要求的type属性 $element->setAttribute('type', 'text/javascript'); $document->appendChild($element); echo $document->saveXML($document->childNodes[0]);
这段代码会输出符合XHTML 1.0附录C的结果:
<script type="text/javascript"><![CDATA[console.log(1 && 1);]]></script>
额外说明:兼顾HTML兼容性的小技巧
如果还要适配老式HTML解析器(它们可能不识别CDATA语法),可以在CDATA前后加上JavaScript注释,这样XML和HTML解析器都能正常处理:
$scriptContent = "//<![CDATA[\nconsole.log(1 && 1);\n//]]>"; $script = $document->createCDATASection($scriptContent);
生成的代码会是:
<script type="text/javascript"><![CDATA[//<![CDATA[ console.log(1 && 1); //]]>]]></script>
这完全符合XHTML 1.0附录C中“兼容HTML的XHTML”的要求,既不会被XML解析器误解析,也能被HTML解析器正确执行脚本。
内容的提问来源于stack exchange,提问作者Jay Bienvenu
相关产品推荐
相关产品推荐

