69

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

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

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

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

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

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

此外,我正在使用我工作的公司内部开发的模板引擎,因此特定于工具包的解决方案对我来说毫无用处。

4

13 回答 13

80

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

\xXX 用于 chars < 127,而 \uXXXX 用于Unicode,因此有了这些知识,您可以为通常白名单之外的所有字符创建强大的JSEncode函数。

例如,

<a href="#" onclick="SelectSurveyItem('<% JSEncode(itemid) %>', '<% JSEncode(itemname) %>'); return false;">Select</a>
于 2008-09-18T22:51:10.597 回答
23

根据服务器端语言,您可以使用以下其中一种:

.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) %>
于 2011-12-23T03:15:57.477 回答
11

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

例如,span for<%itemid%>看起来像<span id='itemid' style='display:none'><%itemid%></span>并且在 javascript 函数SelectSurveyItem中从这些 spans' 中选择参数innerHTML

于 2009-02-03T08:27:04.487 回答
9

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

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

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

于 2008-09-18T22:21:20.437 回答
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>
于 2008-09-18T22:35:42.727 回答
4

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

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

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

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

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

于 2008-09-18T22:41:17.627 回答
1

在 <head> 部分声明单独的函数并在 onClick 方法中调用这些函数。如果你有很多,你可以使用一个命名方案来给它们编号,或者在你的 onClicks 中传递一个整数,并在函数中有一个大的胖 switch 语句。

于 2008-09-18T22:18:33.187 回答
1

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

于 2008-09-18T22:18:49.973 回答
1

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

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

</script>

然后 itemid 和 itemname 需要为 JavaScript 进行转义(即"成为\"等)。

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

于 2008-09-18T22:32:28.333 回答
1

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

于 2008-09-19T15:20:05.547 回答
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;
}
于 2012-02-15T23:28:41.143 回答
0

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

所以。JavaScript 无法处理字符串 'Marge 对 Peter 说“我认为那是”',您需要在将数据提供给脚本之前对其进行清理吗?

于 2008-09-19T11:35:07.157 回答
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);
}
于 2011-03-11T13:05:59.603 回答