(请关注安全性或窗外的任何问题,作为内部应用程序)
基本上我想要做的是在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
}
答案 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
那里的演示包括:
访问此页面以获取更多信息,下载包含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"}"
非常有用!