在 JSON 中传递 javascript 函数
Passing javascript function in JSON
我正在尝试使用单击事件处理程序实现 jQCloud 词云。它要求我在 JSON.
中传递一个 javascript 函数
在 C# 中,我制作了动态 JSON 文本
foreach (var r in result)
{
sbChart.Append("{\"text\": \"" + r.Key + "\", \"weight\": " + r.Count().ToString() + ", ");
sbChart.Append("\"handlers\": { \"click\": \"function() { alert('You clicked " + r.Key + "');}\"}}, ");
}
if (sbChart.Length != 0)
{
returnString = "[" + sbChart.ToString().Substring(0, sbChart.Length - 2) + "]";
}
我 return 通过 web 方法到 javascript 我的代码是
var words = JSON.parse(strJSON);
$('#div').jQCloud(words);
生成的JSON是
[
{"text": "the", "weight": 111, "handlers": { "click": "function() { alert('You clicked the');}"}},
{"text": "in", "weight": 66, "handlers": { "click": "function() { alert('You clicked in');}"}}
]
但是,由于我的函数是一个字符串,所以它不会作为对象执行。如果我删除函数语句前后的双引号,它会在解析期间给我 Invalid Character
错误。
任何人都可以帮助我如何使此警报起作用?
函数不应该作为 JSON 传递,执行数据调用传递的任意逻辑是一个相当大的安全问题。也就是说,使用 eval
来解决这个问题。
类似
var action = eval(response[0].handlers.click); // evaluates the string as javascript, and returns the value, in this case a function.
action();
如果您确实以这种方式将函数传递给您的页面(请参阅下面的"but"),您可以为它使用 eval
,因为你是提供文本的人,你将 eval
ing 它没有安全问题(而且速度问题不是问题,并且一直多年)。我不确定你想用这个函数做什么,但是例如:
$(".foo").on("click", eval(words[0].handlers.click));
...将评估函数并将结果分配为与 .foo
选择器匹配的元素的点击处理程序。
但是,几乎可以肯定有更好的方法来构建事物。不是在 JSON 中传回函数,您可能在 JavaScript 中已经在某种映射中拥有这些函数:
var clickHandlers = {
"the": function() { alert("You clicked the"); },
"in": function() { alert("You clicked the"); }
};
...然后在您的 JSON.
中给出密钥 ("the"
, "in"
)
或者,假设除了被点击的内容之外它们是相同的东西,从被点击的元素中找出被点击的内容("the" 或 "in")。
或其他许多东西中的任何一个,但它们的共同点是函数是在您的 JavaScript 代码中定义的,而不是通过 JSON 发回的,然后您 link 通过 JSON 中的信息而不是 JSON.
中的实际 函数 来增加这些函数
非常感谢您提出以上建议。但我最终使用了 how to provide a click handler in JQCloud
的答案
我根据自己的要求对其进行了一些修改,并且成功了
var tag_list = new Array();
var obj = GetCustomJsonObj(strJSON);
for (var i = 0; i < obj.length; i++) {
tag_list.push({
text: obj[i].text,
weight: obj[i].weight,
//link: obj[i].link,
handlers: {
click: function () {
var zz = obj[i];
return function () {
alert("you have clicked " + zz.text);
}
}()
}
});
}
我正在尝试使用单击事件处理程序实现 jQCloud 词云。它要求我在 JSON.
中传递一个 javascript 函数在 C# 中,我制作了动态 JSON 文本
foreach (var r in result)
{
sbChart.Append("{\"text\": \"" + r.Key + "\", \"weight\": " + r.Count().ToString() + ", ");
sbChart.Append("\"handlers\": { \"click\": \"function() { alert('You clicked " + r.Key + "');}\"}}, ");
}
if (sbChart.Length != 0)
{
returnString = "[" + sbChart.ToString().Substring(0, sbChart.Length - 2) + "]";
}
我 return 通过 web 方法到 javascript 我的代码是
var words = JSON.parse(strJSON);
$('#div').jQCloud(words);
生成的JSON是
[
{"text": "the", "weight": 111, "handlers": { "click": "function() { alert('You clicked the');}"}},
{"text": "in", "weight": 66, "handlers": { "click": "function() { alert('You clicked in');}"}}
]
但是,由于我的函数是一个字符串,所以它不会作为对象执行。如果我删除函数语句前后的双引号,它会在解析期间给我 Invalid Character
错误。
任何人都可以帮助我如何使此警报起作用?
函数不应该作为 JSON 传递,执行数据调用传递的任意逻辑是一个相当大的安全问题。也就是说,使用 eval
来解决这个问题。
类似
var action = eval(response[0].handlers.click); // evaluates the string as javascript, and returns the value, in this case a function.
action();
如果您确实以这种方式将函数传递给您的页面(请参阅下面的"but"),您可以为它使用 eval
,因为你是提供文本的人,你将 eval
ing 它没有安全问题(而且速度问题不是问题,并且一直多年)。我不确定你想用这个函数做什么,但是例如:
$(".foo").on("click", eval(words[0].handlers.click));
...将评估函数并将结果分配为与 .foo
选择器匹配的元素的点击处理程序。
但是,几乎可以肯定有更好的方法来构建事物。不是在 JSON 中传回函数,您可能在 JavaScript 中已经在某种映射中拥有这些函数:
var clickHandlers = {
"the": function() { alert("You clicked the"); },
"in": function() { alert("You clicked the"); }
};
...然后在您的 JSON.
中给出密钥 ("the"
, "in"
)
或者,假设除了被点击的内容之外它们是相同的东西,从被点击的元素中找出被点击的内容("the" 或 "in")。
或其他许多东西中的任何一个,但它们的共同点是函数是在您的 JavaScript 代码中定义的,而不是通过 JSON 发回的,然后您 link 通过 JSON 中的信息而不是 JSON.
中的实际 函数 来增加这些函数非常感谢您提出以上建议。但我最终使用了 how to provide a click handler in JQCloud
的答案我根据自己的要求对其进行了一些修改,并且成功了
var tag_list = new Array();
var obj = GetCustomJsonObj(strJSON);
for (var i = 0; i < obj.length; i++) {
tag_list.push({
text: obj[i].text,
weight: obj[i].weight,
//link: obj[i].link,
handlers: {
click: function () {
var zz = obj[i];
return function () {
alert("you have clicked " + zz.text);
}
}()
}
});
}