格式规范的<script>标签为何在Nokogiri::HTML严格模式下引发解析错误?
问题原因与解决方案
你遇到的这个问题其实是XML严格解析规则和HTML解析规则的差异导致的,咱们一步步拆解:
为什么会报错?
你的测试用例里用了Nokogiri::HTML但传入了Nokogiri::XML::ParseOptions::STRICT——这相当于强制用XML的严格规则去解析HTML内容。
在XML的严格模式下,解析器不会把<script>标签的内容当作特殊的脚本文本处理,它会逐字解析里面的所有内容:
- 你的原始HTML字符串
<script> $('<a></a>') </script>会被先转义成:<script> $('</a>') </script> - XML解析器看到里面的
<a>,会把它当成一个未闭合的XML标签,后面的</a>就变成了一个无匹配的闭合标签,自然就抛出了Unexpected end tag : a的错误。
而HTML解析器本身就知道<script>标签内的内容是脚本代码,不会尝试解析里面的HTML标签,哪怕是严格模式也会正确处理这种场景。
修复方案
方案1:使用HTML的严格解析选项
把XML的解析选项换成HTML专属的严格模式,这样既保留严格校验,又遵循HTML的解析规则:
def test_strict_Nokogiri html = "<script> $('<a></a>') </script>" # 改用HTML的STRICT选项 doc = Nokogiri::HTML(html, nil, nil, Nokogiri::HTML::ParseOptions::STRICT) assert_empty doc.errors end
方案2:给脚本内容包裹CDATA(如果一定要用XML严格模式)
如果你必须使用XML的严格解析规则,需要手动把<script>内的代码用CDATA块包裹,告诉XML解析器这部分是纯文本,不要解析:
def test_strict_Nokogiri # 给脚本内容加上CDATA包裹 html = "<script>//<![CDATA[ $('<a></a>') //]]></script>" doc = Nokogiri::HTML(html, nil, nil, Nokogiri::XML::ParseOptions::STRICT) assert_empty doc.errors end
这样修改后,你的断言就能通过啦!
内容的提问来源于stack exchange,提问作者Phlip
相关产品推荐
相关产品推荐

