我有这个C#对象:
var obj = new {
username = "andrey",
callback = "function(self) { return function() {self.doSomething()} (this) }"
}
我需要对其进行JSON序列化,以通过ajax调用传递给浏览器。我使用JavascriptSerializer,但是它序列化为以下JSON:
{"username":"andrey", "callback": "function(self) { return function() {self.doSomething()} (this) }"}
但是我需要的是:
{"username":"andrey", "callback": function(self) { return function() {self.doSomething()} (this) }}
现在,当JSON对象到达浏览器并被创建时,'callback'参数不是函数而是字符串。知道如何解决它,最好是在服务器端吗?
此行为是故意的。 JSON不应包含任何非数据的内容-在您的情况下为可执行函数。如果数据可以以JSON格式从服务器返回,则该浏览器将面临巨大的安全风险,该JSON格式的服务器在执行时将运行任意功能(可以窃取信息,将用户重定向到恶意网站等)。
JSON的早期实现依赖这样一个事实,即返回的数据可以简单地通过eval()执行以获取对象。但是,人们几乎[[立即意识到这带来了巨大的安全风险,并且此后一直在努力应对。这就是为什么在标准化JSON对象出现之前,人们停止将原始JSON数据放入eval()并改用JSON解析库的原因。
JSON对象将始终仅将对象序列化为数据。这是设计使然。标准化JSON格式无法表示可执行函数。现在,您可以通过将其传递给eval()轻松地在浏览器上将该回调转换为函数。但是,
不要这样做
。您只是在为黑客开放自己。[在服务器端,现代的浏览器旨在防止发生这种确切的事情-即,从包含可执行功能的浏览器发送数据。我能够使用Json.net库(使用JsonConvert和JRaw)获得所需的输出。
示例:
// set the property value using JRaw
var obj = new {
username = "andrey",
callback = new JRaw("function(self) { return function() {self.doSomething()} (this) }")
}
// and then serialize using the JsonConvert class
var jsonObj = JsonConvert.SerializeObject(obj);
这应该为您提供带有函数的json对象(而不是字符串中的函数)。帖子:How to serialize a function to json (using razor @<text>)
在您的json中,将callback属性设置为描述Function构造函数参数的字符串数组。然后,当json数据到达客户端时,您必须将Array转换为Function对象的实例。
这样,您可以在后台数据库中获得函数实现的详细信息,而不是在源代码中进行硬编码。
const json = '{"username":"andrey","callback":["self","return self.doSomething()"]}';
//Parse the json to an object
const object = JSON.parse(json);
//Convert the callback property from Array to Function
object["callback"] = new Function(...object["callback"]);
//Create a parameter for calling the Function
var self = {
doSomething() {
console.log("Do something called");
}
}
//Call the function
object["callback"](self);