你能"存储"在DB中的javascript,然后在以后执行它?

时间:2016-07-24 01:54:48

标签: javascript node.js

(请关注安全性或窗外的任何问题,作为内部应用程序)

基本上我想要做的是在db中存储一个javascript函数:

 function x(name) {
   return name + 1;
 }

然后稍后获取数据库行

(这里是伪代码)

 x = db.get('function').where('id').equals(1);

 console.log(x('bob'));
 //should print "bob +1 "

所以这是我想象的场景:

基本上,我得到一个JSON对象,并且根据某些标准,我想对该json进行一些转换,并输出新的转换后的json。为了"主要"应用程序,我不想硬编码转换逻辑,而是它将是动态的(在不同的开发人员将在运行时提供它的意义上的动态)

所以数据库可能包含:

ID   |    javascript 
====================
1    |    (some js code)
2    |    (same func, different code)

我想要做的是使用我选择的输入执行存储在DB中的JS代码。

如果它更容易,函数名称将是标准的..即我们可以假设保存在数据库中的javascript将全部遵循:

function transform(input) {
  /* below this line logic will change

* end diff logic/
 return output
}

5 个答案:

答案 0 :(得分:4)

您可以使用eval() function执行任意JS的任意字符串,这将返回已评估的结果。

因此,出于您的目的,您希望指定一个变量来保存字符串中的(eval'ed)函数,您可以这样做:

// retrieve string from DB somehow
var functionString = "(function whatever(name) { return name + 1; })";
var x = eval(functionString);
console.log(x("bob")); // logs "bob1"

请注意,我已将函数包装在括号中的字符串中,因为这使它成为一个函数表达式,然后可以将其赋值给变量x

  

我不想对转换逻辑进行硬编码,而是动态的(在不同开发人员在运行时提供动态的意义上是动态的)

在我看来,另一种更好的方法是将所有转换函数放入一个单独的JavaScript模块,然后根据标准Node.js module loading system require()。这样,转换逻辑在另一个文件中保持独立,可以根据需要由不同的开发人员单独维护,而不会破坏数据库操作和eval()

// transforms.js
module.exports = {
  "1" : function plus1(name) { return name + 1; },
  "2" : function square(x) { return x * x; },
  "3" : function half(x) { return x / 2; }
  // etc.
};

// in main JS file
var transforms = require("./transforms.js");

var a = transforms["2"];
var b = transforms["3"];
console.log(a(b(20))); // 100
console.log(transforms["1"]("bob")); // "bob1"

如上所示,每个“动态”转换函数都被定义为对象的属性,其中属性名称是您将在数据库中使用的键。

StackOverflow代码段似乎不处理模块,但是如果展开以下代码段,您可以看到上述代码的等效代码:

// in "transform.js"
var transforms = {
  "1" : function plus1(name) { return name + 1; },
  "2" : function square(x) { return x * x; },
  "3" : function half(x) { return x / 2; }
  // etc.
};

// in main JS file
var a = transforms ["2"];
var b = transforms ["3"];
console.log(a(b(20))); // 100
console.log(transforms ["1"]("bob")); // "bob1"

答案 1 :(得分:3)

您可以使用eval来执行JS的字符串。我不知道你在做什么,也不知道这是为了什么,但这是非常气馁的。

尝试在您的网络控制台中运行:

eval('alert(\'hello\')')

答案 2 :(得分:2)

您可以在JavaScript中执行此操作。 这是一个例子。

var f = "function(x) {return x * 2}"
var x = 4;
eval("("+f+")("+x+")");

但这是非常不安全的,因为您无法确保您正在执行的功能不包含危险代码。 相反,你可以使用口译员。 要么像这样使用现有的 https://github.com/NeilFraser/JS-Interpreter

或者自己写。它不一定是JS。如果语言很简单,你可以在下午为它写一个翻译。

答案 3 :(得分:2)

Matthias Brantner与Oracle实验室最近展示了一个实验性功能,即多语言引擎(MLE),它允许在Oracle数据库中执行JavaScript:

https://www.youtube.com/playlist?list=PL_lVOJzXeE_8UwipLqfu6vKnOYDF3ITaI

那里的演示包括:

  • JavaScript模块作为SQL中的UDF
  • Oracle数据库中的JavaScript SQL驱动程序
  • Oracle数据库中的Sequelize ORM
  • SQL中基于JavaScript的聚合函数

访问此页面以获取更多信息,下载包含DB + MLE的VM,并通过MLE社区提供反馈:http://www.oracle.com/technetwork/database/multilingual-engine/overview/index.html

答案 4 :(得分:0)

eval()对于为活动对象设置持久性的决定不是很好:

例如,让我们看一个简单的框架对象:

o = { type:'obj', value:'o', dump: function() { return "<"+this.type+":"+this.value+">" } }

> {type: "obj", value: "o", dump: ƒ}

现在我们要进行eval()可行的表示:

o.toString()

"[object Object]"

JSON.stringify(o)

"{"type":"obj","value":"o"}"

非常有用!