2015-04-18 23 views
3

我正在尝试使用单击事件处理程序实现jQCloud字云。它要求我在JSON中传递一个JavaScript函数。在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) + "]"; 
} 

我通过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错误。

请任何人都可以帮助我,我该如何使此警报工作?

+3

你永远不应该需要传递一个函数这样。如果你觉得有必要,那么也许你应该重新评估你的整体设计。 –

+0

非常感谢您的建议,我改变了我的方法:) – Hitesh

回答

0

非常感谢您的建议。但我最终使用的答案从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); 
        } 
       }() 
      } 
     }); 
    } 
1

函数并不意味着作为JSON传递,并且执行数据调用传递的任意逻辑是一个相当大的安全问题。也就是说,使用eval来解决这个问题。

喜欢的东西

var action = eval(response[0].handlers.click); // evaluates the string as javascript, and returns the value, in this case a function. 

action(); 
+0

如果Hitesh是创建JSON的人,您会发现什么安全问题?如何从您控制的服务器加载JSON文件,您担心从您控制的服务器加载JavaScript文件不在哪里? –

+0

你说得对,因为你控制了数据调用,只要你确定你没有评估用户提供的内容(xss问题),它就不应该变得更加脆弱。 http://stackoverflow.com/questions/197769/when-is-javascripts-eval-not-evil是一个伟大的小片段。在这种情况下更具哲理意义。 –

2

如果你绝对给一个函数传递给你的页面的方式(见“而是”下面),你可以使用eval它,因为你提供文本的人不会遇到安全问题(并且速度问题不是问题,并且已经存在多年)。我不知道你想要的功能做什么,但例如:

$(".foo").on("click", eval(words[0].handlers.click)); 

...将EVAL的功能,并将结果指定为在.foo选择匹配的元素的单击处理程序。

但是,几乎可以肯定有更好的方法来构造东西。而是回传功能的JSON的,你可能在你的JavaScript这些功能已经在某种地图:

var clickHandlers = { 
    "the": function() { alert("You clicked the"); }, 
    "in": function() { alert("You clicked the"); } 
}; 

...然后刚刚给你JSON的关键("the""in")。

或者,鉴于它们与被点击的内容不同,因此找出被点击的元素被点击的内容(“the”或“in”)。

或其他任何东西,但它们的共同之处在于函数是在JavaScript代码中定义的,不是通过JSON发回的,然后通过JSON中的信息而不是实际的方式将这些函数链接起来函数在JSON中。