代码之家  ›  专栏  ›  技术社区  ›  Oliver Williams

通过AJAX传递带有函数的JSON

  •  1
  • Oliver Williams  · 技术社区  · 6 年前

    很简单,我想“重新混合”从AJAX传递的函数,如下所示:

    //AJAX response:
    {"foo":"bar","baz":"function(){console.log('I am back working as a function!');}"}
    

    baz 应该是函数而不是字符串。我该怎么做?

    2 回复  |  直到 6 年前
        1
  •  1
  •   Terry Lennox    6 年前

    评估。。使用风险自负!!

    var ajaxResponse = {"foo":"bar","baz":"function(){console.log('I am back working as a function!')}", "lambda": "() => console.log('Hello i\\'m a lambda')"};
    
    function isAFunction(v) {
        try {
            eval("var f = " + v);
            return typeof f === "function";
        } catch (e) {
            return false;
        }
    }
    
    var result = Object.entries(ajaxResponse).reduce((obj, [key,value]) => {
          if (isAFunction(value)) {
              eval("obj[key] = " + value);
          } else {
                obj[key] = value;
          }
          return obj;
          
    }, {});
    
    result.baz();
    result.lambda();
        2
  •  2
  •   wsdt    6 年前

    正如Jozef所建议的 eval() .

    1. https://javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval/
    2. When is JavaScript's eval() not evil?
    3. https://javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval/
    4. Why is using the JavaScript eval function a bad idea?

    正如这个博客所暗示的( http://2ality.com/2014/01/eval.html )我建议你用这个:

    let json = {"foo":"bar","baz":"function(){console.log('I am back working as a function!');}"};
    
    let func = new Function("console.log('I am back working as a function!');");
    func();

    如果您无法更改json,那么您可以简单地使用 str.replace() .


    请记住,可以执行任意代码! 我会的 建议你这样做,而不是仅仅用函数来回应。通过执行以下操作,您将获得某种白名单。因此,无论http响应是否被操纵,攻击者都只能执行预定义的javascript函数。

    function func1() {
      console.log('I am back working as a function!');
    }
    
    function func2() {
      console.log('another code block');
    }
    
    let json = {"foo":"bar","baz":"1"};
    
    switch(json.baz) {
      case "1": func1();break;
      case "2": func2();break;
      default: console.error("Invalid response");
    }

    我希望这有帮助。