使用Spring在HTML中转义撇号

时间:2019-02-05 23:34:16

标签: javascript java html spring escaping

我在某些旧版代码中有一个错误,在尝试对其进行修复时,发现了我不理解的行为。该应用程序是使用JSP和JSTL的Spring MVC应用程序。下面是一个简化的示例,它复制了我正在谈论的行为。我控制器的代码是:

@GetMapping("/users/thing")
public ModelAndView thing() {

    ModelAndView model = new ModelAndView("users/thing");
    String stringWithApostrophe = "Any'String";
    String escapedWithHtmlUtils = HtmlUtils.htmlEscape(stringWithApostrophe);

    model.addObject("stringWithApostrophe", stringWithApostrophe);
    model.addObject("escapedWithHtmlUtils", escapedWithHtmlUtils);
    return model;
}

变量stringWithApostrophe中包含撇号,然后我对其进行转义并将转义的值存储在其他变量中。之后,将它们都添加到模型中。

我的看法是这样的:

<p><a onClick="clicked('${stringWithApostrophe}');" href="#">stringWithApostrophe: ${stringWithApostrophe}</a></p>
<p><a onClick="clicked('${escapedWithHtmlUtils}');" href="#">escapedWithHtmlUtils: ${escapedWithHtmlUtils}</a></p>

<script type="text/javascript">
    function clicked(text){
        console.log(text);
    }
</script>

如果我在浏览器中按CTRL+U以查看页面的来源,则会看到以下内容:

<p><a onClick="clicked('Any'String');" href="#">stringWithApostrophe: Any'String</a></p>
<p><a onClick="clicked('Any&#39;String');" href="#">escapedWithHtmlUtils: Any&#39;String</a></p>

...看起来不错,并且呈现为:

screenshot of html rendered by browser

...这也是我所期望的。当我单击第一个链接时,它也按预期失败,由于未转义的撇号破坏了JavaScript代码,浏览器控制台显示了错误消息Syntax error: missing ) after argument list

但是,尽管我希望第二个链接能够正常工作,但它也会失败,并显示相同的错误消息。为什么会这样呢?我无法理解,撇号已转换为CTRL+U所示的html实体,因此它不应破坏javascript。我一直在互联网上寻找造成这种情况的可能原因,但没有发现任何问题。我想念什么?

更新:我上载了the example project,如果有帮助,我曾经将错误重现到Github。

1 个答案:

答案 0 :(得分:1)

如您的问题所述,撇号已由HtmlUtils类成功转换为HTML实体引用,成为&#39;。之所以发生您描述的行为,是因为HTML解析器在将内容传递给JavaScript引擎之前会解析属性值中的实体引用。因此,onclick(...)语句中的实体被解码为原始字符',如下所示。

onClick="clicked('Any&#39;String');" => onClick="clicked('Any'String');"

因此,对于JS引擎,两个onClick(...)语句是等效的。

有关此问题的更多信息,请参见this related discussion讨论。