如何在onClick处理程序中的JavaScript代码内转义字符串?

时间:2020-03-06 14:23:49  来源:igfitidea点击:

也许我只是在想这件事太难了,但是在弄清楚要在链接的onClick处理程序中的某些JavaScript代码中的字符串上使用什么转义时,我遇到了问题。例子:

<a href="#" onclick="SelectSurveyItem('<%itemid%>', '<%itemname%>'); return false;">Select</a>

" <%itemid%>"和" <%itemname%>"是发生模板替换的地方。我的问题是项目名称可以包含任何字符,包括单引号和双引号。当前,如果包含单引号,则会中断JavaScript代码。

我的第一个想法是使用模板语言的函数对项目名称进行JavaScript转义,而转义引号。这不能解决包含双引号的字符串的情况,这会破坏链接的HTML。通常如何解决此问题?我是否需要对整个onClick处理程序进行HTML转义?

如果是这样的话,这看起来真的很奇怪,因为模板语言的转义功能还会HTML化括号,引号和分号...

该链接是针对搜索结果页面中的每个结果生成的,因此无法在JavaScript标记内创建单独的方法,因为我需要为每个结果生成一个。

另外,我使用的模板引擎是我工作的公司自己开发的,因此工具包特定的解决方案对我来说毫无用处。

解决方案

在<head>部分中声明单独的函数,然后在onClick方法中调用它们。如果我们有很多,则可以使用一种为它们编号的命名方案,或者在onClicks中传递一个整数,然后在函数中使用一个大的switch语句。

使用包含JavaScript编码的Microsoft Anti-XSS库。

如果要进入HTML属性,则需要对其进行HTML编码(至少:` -引号(带有反斜杠),这样它们就不会干扰JavaScript引号。

最好的方法是使用模板系统(如有必要,对其进行扩展),但是我们可以简单地进行几个转义/编码功能,并将它们包装在其中的任何数据周围。

是的,对HTML属性的全部内容进行HTML转义(即使它们包含javascript)也是完全有效的(甚至是正确的)。

首先,如果以这种方式设置onclick处理程序,则会更简单:

<a id="someLinkId"href="#">Select</a>
<script type="text/javascript">
  document.getElementById("someLinkId").onClick = 
   function() {
      SelectSurveyItem('<%itemid%>', '<%itemname%>'); return false;
    };

</script>

然后,需要对JavaScript的itemid和itemname进行转义(即,""变成" ""等)。

如果在服务器端使用Java,则可以查看雅加达common-lang中的StringEscapeUtils类。否则,编写自己的" escapeJavascript"方法应该不会花费太长时间。

尝试避免在HTML中使用字符串文字,并使用JavaScript绑定JavaScript事件。

另外,除非我们真的知道自己在做什么,否则避免使用" href =#"。对于强制性的中间点击器(选项卡打开器),它破坏了太多的可用性。

<a id="tehbutton" href="somewhereToGoWithoutWorkingJavascript.com">Select</a>

我选择的JavaScript库恰好是jQuery:

<script type="text/javascript">//<!-- <![CDATA[
jQuery(function($){
   $("#tehbutton").click(function(){
        SelectSurveyItem('<%itemid%>', '<%itemname%>');
        return false;
   });
});
//]]>--></script>

如果我们恰巧呈现了这样的链接列表,则可能需要这样做:

<a id="link_1" href="foo">Bar</a>
<a id="link_2" href="foo2">Baz</a>

<script type="text/javascript">
   jQuery(function($){
        var l = [[1,'Bar'],[2,'Baz']];
        $(l).each(function(k,v){
           $("#link_" + v[0] ).click(function(){
                SelectSurveyItem(v[0],v[1]);
                return false;
           });
        });
   });
 </script>

另一个有趣的解决方案可能是这样做:

<a href="#" itemid="<%itemid%>" itemname="<%itemname%>" onclick="SelectSurveyItem(this.itemid, this.itemname); return false;">Select</a>

然后,我们可以在两个变量上使用标准的HTML编码,而不必担心javascript引用的额外复杂性。

是的,这确实会创建严格无效的HTML。但是,这是一种有效的技术,所有现代浏览器都支持该技术。

如果是我的话,我可能会同意我的第一个建议,并确保这些值经过HTML编码并转义了单引号。

在JavaScript中,我们可以将单引号编码为" \ x27",将双引号编码为" \ x22"。因此,使用这种方法,一旦进入JavaScript字符串文字的(双引号或者单引号)引号,就可以使用\ x27 \ x22而不受惩罚,而不必担心会出现任何嵌入的引号"突破"字符串的情况。

\ xXX用于<127的字符,\ uXXXX用于Unicode,因此有了这些知识,我们可以为所有不在常规白名单中的字符创建一个健壮的JSEncode函数。

例如,

<a href="#" onclick="SelectSurveyItem('<% JSEncode(itemid) %>', '<% JSEncode(itemname) %>'); return false;">Select</a>

是这里的答案,我们不能使用JavaScript转义引号,而需要以转义的字符串开头。

所以。 JavaScript无法处理字符串" Marge对Peter说"我会那样看"",我们需要在将数据提供给脚本之前清除数据吗?

任何值得赞扬的模板引擎都将具有"转义引号"功能。我们的(也是我自己工作的地方)也具有转义javascript引号的功能。在这两种情况下,模板变量都只添加_esc或者_js_esc,具体取决于所需的变量。绝不要将用户生成的内容输出到尚未逃脱的浏览器,恕我直言。

使用隐藏的跨度,每个跨度分别用于参数<%itemid%>和<%itemname%>并将其值写入其中。

例如," <%itemid%>"的跨度看起来像是" <span id ='itemid'style ='display:none'> <%itemid%> </ span>`"以及在JavaScript函数" SelectSurveyItem"中从这些跨度的" innerHTML"中选择参数。