我在一些旧代码中发现了一个错误,尝试修复它时发现了一个我不理解的行为。该应用程序是一个使用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'String');" href="#">escapedWithHtmlUtils: Any'String</a></p>
...看起来不错,渲染结果如下:
...这也是我预期的结果。当我点击第一个链接时,它也像预期的那样失败了,浏览器控制台显示错误信息Syntax error: missing ) after argument list
,因为未转义的撇号破坏了javascript代码。
然而,尽管我预期第二个链接可以工作,但它也失败了,并显示相同的错误消息。为什么会这样?我无法理解,撇号被转换为HTML实体,如CTRL+U
所示,因此它不应该破坏javascript。我在互联网上寻找可能导致此问题的原因,但没有发现任何东西。我漏掉了什么吗?
更新:我已经将我用于重现错误的示例项目上传到Github,以防有用。
'Any\'String'
- xehpukAny'String
是一个有效的Javascript字符串,为什么我需要对它进行转义? - joanlofe