使用Spring在HTML中转义单引号

3

我在一些旧代码中发现了一个错误,尝试修复它时发现了一个我不理解的行为。该应用程序是一个使用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>

...看起来不错,渲染结果如下:

浏览器渲染的html截图

...这也是我预期的结果。当我点击第一个链接时,它也像预期的那样失败了,浏览器控制台显示错误信息Syntax error: missing ) after argument list,因为未转义的撇号破坏了javascript代码。

然而,尽管我预期第二个链接可以工作,但它也失败了,并显示相同的错误消息。为什么会这样?我无法理解,撇号被转换为HTML实体,如CTRL+U所示,因此它不应该破坏javascript。我在互联网上寻找可能导致此问题的原因,但没有发现任何东西。我漏掉了什么吗?

更新:我已经将我用于重现错误的示例项目上传到Github,以防有用。


你需要在JavaScript和HTML中对其进行转义,我猜测应该是:'Any\&#39;String' - xehpuk
但是 Any&#39;String 是一个有效的Javascript字符串,为什么我需要对它进行转义? - joanlofe
1个回答

1
正如您的问题所述,撇号已成功转换为HTML实体引用,成为&#39;。您描述的行为之所以发生是因为HTML解析器在将内容交给JavaScript引擎之前解析属性值中的实体引用。因此,在onclick(...)语句中的实体被解码为原始字符',如下所示。 onClick="clicked('Any&#39;String');" => onClick="clicked('Any'String');"
因此,对于JS引擎而言,这两个onClick(...)语句是等效的。
有关此问题的更多信息,请参见this related discussion讨论。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接