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

时间:2008-09-18 22:16:22

标签: javascript html string escaping

也许我只是在考虑这个问题,但是我在查找链接的onClick处理程序中某些JavaScript代码中的字符串转义时遇到了什么问题。例如:

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

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

我的第一个想法是使用模板语言的函数来JavaScript转义项目名称,它只是逃避引号。这不会修复包含双引号的字符串的情况,该双引号会破坏链接的HTML。这个问题通常是如何解决的?我是否需要HTML-escape整个onClick处理程序?

如果是这样,那看起来很奇怪,因为模板语言的转义函数也会使括号,引号和分号HTML化......

此搜索结果页面中的每个结果都会生成此链接,因此无法在JavaScript代码中创建单独的方法,因为我需要为每个结果生成一个。

另外,我正在使用我工作的公司本土化的模板引擎,因此特定于工具包的解决方案对我没有用。

13 个答案:

答案 0 :(得分:77)

在JavaScript中,您可以将单引号编码为“\ x27”,将双引号编码为“\ x22”。因此,使用此方法,您可以在JavaScript字符串文字的(双引号或单引号)内部使用\ x27 \ x22而不用担心任何嵌入式引号“突破”您的字符串。

\ xXX用于字符&lt; 127,以及Unicode的\ uXXXX,因此您可以使用这些知识为所有超出常规白名单的字符创建强大的 JSEncode 函数。

例如,

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

答案 1 :(得分:20)

根据服务器端语言,您可以使用以下方法之一:

.NET 4.0

string result = System.Web.HttpUtility.JavaScriptStringEncode("jsString")

爪哇

import org.apache.commons.lang.StringEscapeUtils;
...

String result = StringEscapeUtils.escapeJavaScript(jsString);

的Python

import json
result = json.dumps(jsString)

PHP

$result = strtr($jsString, array('\\' => '\\\\', "'" => "\\'", '"' => '\\"', 
                                 "\r" => '\\r', "\n" => '\\n' ));

Ruby on Rails

<%= escape_javascript(jsString) %>

答案 2 :(得分:10)

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

例如,<%itemid%>的范围看起来像<span id='itemid' style='display:none'><%itemid%></span>,而javascript函数SelectSurveyItem则从这些范围innerHTML中选择参数。

答案 3 :(得分:9)

请尽量避免在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>

答案 4 :(得分:8)

如果它进入HTML属性,则需要进行HTML编码(至少:>&gt; <&lt和{{ 1}}到")它,转义单引号(带反斜杠),这样它们就不会干扰你的javascript引用。

最好的方法是使用模板系统(必要时扩展它),但你可以简单地制作一些转义/编码函数,并将它们包装在那里的任何数据周围。

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

答案 5 :(得分:3)

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

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

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

是的,此 创建严格无效的HTML。但是, 是一种有效的技术,所有现代浏览器都支持它。

如果是我的话,我可能会考虑我的第一个建议,并确保这些值是HTML编码的并且有单引号转义。

答案 6 :(得分:1)

在&lt; head&gt;中声明单独的函数部分并调用onClick方法中的那些。如果你有很多,你可以使用一个为它们编号的命名方案,或者在你的onClicks中传递一个整数,并在函数中有一个很大的胖开关语句。

答案 7 :(得分:1)

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

答案 8 :(得分:1)

首先,如果以这种方式设置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,那么您可以从jakarta的common-lang中查看类StringEscapeUtils。否则,编写自己的'escapeJavascript'方法不应该花太长时间。

答案 9 :(得分:1)

我也遇到过这个问题。我制作了一个脚本,将单引号转换为不会破坏HTML的转义双引号。

function noQuote(text)
{
    var newtext = "";
    for (var i = 0; i < text.length; i++) {
        if (text[i] == "'") {
            newtext += "\"";
        }
        else {
            newtext += text[i];
        }
    }
    return newtext;
}

答案 10 :(得分:0)

这里的答案是你无法使用JavaScript来逃避引号,并且你需要从转义字符串开始。

因此。没有办法让JavaScript能够处理字符串'Marge说'我认为那是“给Peter”并且你需要在将数据提供给脚本之前清理它?

答案 11 :(得分:0)

任何有价值的模板引擎都会有一个“逃避引号”功能。我们(也是本土的,我工作的地方)也有一个功能来逃避javascript的引用。在这两种情况下,模板变量只是附加_esc或_js_esc,具体取决于您想要的。您永远不应该将用户生成的内容输出到尚未转义的浏览器,恕我直言。

答案 12 :(得分:0)

我遇到了同样的问题,我以一种棘手的方式解决了这个问题。首先创建全局变量v1,v2和v3。在onclick中,发送一个指示符1,2或3,并在功能检查1,2,3中将v1,v2和v3放在:

onclick="myfun(1)"
onclick="myfun(2)"
onclick="myfun(3)"

function myfun(var)
{
    if (var ==1)
        alert(v1);

    if (var ==2)
        alert(v2);

    if (var ==3)
        alert(v3);
}