【问题标题】:Passing javascript function in JSON在 JSON 中传递 javascript 函数
【发布时间】:2015-06-25 05:15:32
【问题描述】:

我正在尝试使用单击事件处理程序实现 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) + "]";
}

我通过网络方法将此返回到我的代码所在的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 错误。

请任何人帮助我如何使此警报起作用?

【问题讨论】:

  • 您永远不需要以这种方式传递函数。如果您认为有必要,那么也许您应该重新评估您的整体设计。
  • 非常感谢您的建议,我改变了方法:)

标签: javascript c# jquery json word-cloud


【解决方案1】:

非常感谢您的上述建议。但我最终使用了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);
                    }
                }()
            }
        });
    }

【讨论】:

  • 您自己想通了很好,但您的答案与您提出的问题完全不同。在这个答案中,您没有按照最初的要求传递 javascript 函数。因此,将其标记为上述问题的已接受答案有点误导。
【解决方案2】:

如果您绝对必须以这种方式将函数传递给您的页面(请参阅下面的“但是”),您可以使用eval,因为您'是提供文本的人evaling 它没有安全问题(速度问题不是问题,并且已经存在多年)。我不确定你想用这个函数做什么,但是例如:

$(".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 发回的,然后您通过 JSON 中的信息而不是实际的信息来链接这些函数 函数。

【讨论】:

    【解决方案3】:

    函数不打算作为 JSON 传递,执行数据调用传递的任意逻辑是一个相当大的安全问题。话虽如此,使用eval 来解决这个问题。

    类似

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

    【讨论】:

    • 如果 Hitesh 是创建 JSON 的人,您看到什么安全问题?从您控制的服务器加载 JSON 文件如何让您担心从您控制的服务器加载 JavaScript 文件却不担心?
    • 你是对的,既然你控制了数据调用,它不应该更容易受到攻击,只要你确定你不评估用户提供的内容(xss 问题)。 stackoverflow.com/questions/197769/… 是一个很棒的小sn-p。在这种情况下,哲学意义大于意义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-21
    • 1970-01-01
    • 2017-11-10
    • 1970-01-01
    • 2013-09-25
    • 1970-01-01
    相关资源
    最近更新 更多