JSON serializing an object with function parameter

后端 未结 3 1564
失恋的感觉
失恋的感觉 2021-01-01 22:46

I have this C# object:

var obj = new {
    username = \"andrey\",
    callback = \"function(self) { return function() {self.doSomething()} (this) }\"
}


        
相关标签:
3条回答
  • 2021-01-01 23:03

    I was trying to accomplish something similar. In my case I was using MVC Razor syntax trying to generate a json object with a function passed in using the @<text> syntax.

    I was able to get the desired output using the Json.net library (using JsonConvert and JRaw).

    Example:

    // 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);
    

    That should get you the json object with the function (instead of the function in a string).

    Post: How to serialize a function to json (using razor @<text>)

    0 讨论(0)
  • 2021-01-01 23:07

    You can make use of the constructor of the Function object. See https://developer.mozilla.org/nl/docs/Web/JavaScript/Reference/Global_Objects/Function.

    In your json you set the callback property to a string array that describes the Function constructor parameters. Then when the json data has arrived on the client you have to convert the Array to an instance of the Function object.

    This way you can have the function implementation details in your back database instead of hardcoded in source code.

    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);
    
    0 讨论(0)
  • 2021-01-01 23:29

    This behavior is deliberate. JSON should not include anything that is not data -- in your case an executable function. The browser will be opening up to huge security risks if data can come back from a server in JSON format that, when executed, will run arbitrary functions (that can steal info, redirect the user to a malicious site etc.)

    Early implementations of JSON rely on the fact that data returned back can be simply executed via eval() to get back an object. However, people almost immediately realized that this opens up huge security risks and have been trying to handle it since. That's why, before the standardized JSON object, people stopped putting raw JSON data into eval() and used JSON parsing libraries instead.

    The JSON object will always serialize an object into data only. This is by design. THe standardized JSON format has no way to represent an executable function.

    Now, you can easily convert that callback on a browser into a function by passing it through to eval(). However, don't do it. You're just opening yourself up for hacking.

    On the server side, modern browsers are designed to prevent this exact thing from happening -- i.e. data being sent from a browser that contains an executable function.

    0 讨论(0)
提交回复
热议问题