如何转义 onClick 处理程序内 JavaScript 代码中的字符串?
-
01-07-2019 - |
题
也许我只是想得太难了,但我在弄清楚链接的 onClick 处理程序内的某些 JavaScript 代码中的字符串上使用什么转义时遇到了问题。例子:
<a href="#" onclick="SelectSurveyItem('<%itemid%>', '<%itemname%>'); return false;">Select</a>
这 <%itemid%>
和 <%itemname%>
是发生模板替换的地方。我的问题是项目名称可以包含任何字符,包括单引号和双引号。目前,如果它包含单引号,则会破坏 JavaScript 代码。
我的第一个想法是使用模板语言的函数来转义项目名称,它只是转义引号。这不会修复包含双引号的字符串的大小写问题,从而破坏链接的 HTML。通常如何解决这个问题?我需要对整个 onClick 处理程序进行 HTML 转义吗?
如果是这样,那看起来真的很奇怪,因为模板语言的转义函数也会将括号、引号和分号 HTML 化......
该链接是为搜索结果页面中的每个结果生成的,因此不可能在 JavaScript 标记内创建单独的方法,因为我需要为每个结果生成一个方法。
另外,我使用的是我工作的公司自行开发的模板引擎,因此特定于工具包的解决方案对我来说没有用处。
解决方案
在 JavaScript 中,您可以将单引号编码为“\x27”,将双引号编码为“\x22”。因此,使用此方法,一旦您位于 JavaScript 字符串文字的(双或单)引号内,您就可以不受惩罚地使用 \x27 \x22 ,而不必担心任何嵌入的引号“破坏”您的字符串。
\xXX 表示小于 127 的字符,\uXXXX 表示 统一码, ,因此有了这些知识,您就可以创建一个强大的 JS编码 功能适用于通常白名单之外的所有字符。
例如,
<a href="#" onclick="SelectSurveyItem('<% JSEncode(itemid) %>', '<% JSEncode(itemname) %>'); return false;">Select</a>
其他提示
根据服务器端语言,您可以使用其中之一:
.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' ));
红宝石 on Rails
<%= escape_javascript(jsString) %>
使用隐藏跨度,每个参数各一个 <%itemid%>
和 <%itemname%>
并将他们的价值观写在里面。
例如,跨度为 <%itemid%>
看起来像 <span id='itemid' style='display:none'><%itemid%></span>
并在 JavaScript 函数中 SelectSurveyItem
从这些跨度中选择参数' innerHTML
.
尽量避免在 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>
如果它进入 HTML 属性,您将需要进行 HTML 编码(至少: >
到 >
<
到 <
和 "
到 "
) 它, 和 转义单引号(带有反斜杠),这样它们就不会干扰您的 javascript 引用。
最好的方法是使用模板系统(如果需要,可以扩展它),但是您可以简单地创建几个转义/编码函数,并将它们包装在其中的任何数据周围。
是的,对 HTML 属性的全部内容进行 HTML 转义是完全有效的(甚至是正确的),即使它们包含 javascript。
另一个有趣的解决方案可能是这样做:
<a href="#" itemid="<%itemid%>" itemname="<%itemname%>" onclick="SelectSurveyItem(this.itemid, this.itemname); return false;">Select</a>
然后,您可以对这两个变量使用标准 HTML 编码,而不必担心 javascript 引用的额外复杂性。
是的,这个 做 创建严格无效的 HTML。然而,它 是 一种有效的技术,所有现代浏览器都支持它。
如果是我的话,我可能会采用我的第一个建议,并确保值是 HTML 编码的 和 单引号已转义。
在 <head> 部分中声明单独的函数并在 onClick 方法中调用这些函数。如果你有很多,你可以使用命名方案来对它们进行编号,或者在 onClicks 中传递一个整数,并在函数中使用一个大的 switch 语句。
我也遇到过这个问题。我编写了一个脚本,将单引号转换为转义双引号,这样不会破坏 HTML。
function noQuote(text)
{
var newtext = "";
for (var i = 0; i < text.length; i++) {
if (text[i] == "'") {
newtext += "\"";
}
else {
newtext += text[i];
}
}
return newtext;
}
使用 微软反XSS库 其中包括 JavaScript 编码。
首先,如果 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 进行转义(即 "
变成 \"
, , ETC。)。
如果你在服务器端使用 Java,你可以看看这个类 字符串转义工具 来自雅加达的 common-lang。否则,编写您自己的“escapeJavascript”方法不应花费太长时间。
这里的答案是您无法使用 JavaScript 转义引号,并且需要从转义字符串开始。
所以。JavaScript 无法处理字符串“Marge said “I'd Look that was” to Peter”,并且您需要在将数据提供给脚本之前清理数据吗?
任何好的模板引擎都具有“转义引号”功能。我们的(也是我工作的地方)也有一个转义 JavaScript 引号的功能。在这两种情况下,模板变量都会附加 _esc 或 _js_esc,具体取决于您想要的。恕我直言,您永远不应该将用户生成的内容输出到尚未转义的浏览器。
我遇到了同样的问题,并以一种棘手的方式解决了它。首先创建全局变量 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);
}