使用封闭函数将 Eval 转换为 Node 的 VM 模块
Converting Eval to Node's VM Module with an Enclosed Function
我们正在为我们的 REST 端点使用 Loopback,并且有一个端点从数据库中提取 JavaScript,然后使用 eval 在 Node 实例的服务器上加载和执行特定功能。我们想转换为 Node 的 VM 功能,但是 运行 遇到了问题。具体怎么做:
- 在 'namespace',
中加载具有多种功能的代码
- 执行其中一项功能,
- 允许注入的函数访问导入的模块,
- 然后 return 该函数的结果。
基于 'eval' 的代码运行良好,但似乎已停止使用最新的 Node.因此,我们利用这个机会转换为 Node 的 'vm' 沙盒。但是,我们无法调用嵌入在命名空间中的函数。
// ********************************
// CODE TO CALL THE SERVER END-POINT AND CONSUME THE RETURN
// ********************************
let javaScriptCode = `
namespace QueryLib {
// Execute a query.
export function onQuery(callback) {
// Execute the Query functions from the 'Query' import to retrieve data.
Query.select('RowID', 'CustomerID', 'Name').from('customer').then(function (e, rows) {
callback(e, rows)
})
}
}
`
// Call the end-point and receive the query data.
ServerRestEndPoints.executeDynamicScriptOnServer(javaScriptCode, function (data) {
// Process 'data' here.
});
// ****************************************************************
// SERVER (END-POINT) CODE
// ****************************************************************
// ********************************
// CURRENT VERION USING 'EVAL'
// ********************************
import Query = require("query");
export function executeDynamicScriptOnServer(javaScript, callback) {
// Load the module with the script passed in (pulled from the db).
eval(javaScript);
// Load the function from the dynamic script
let func = eval('onQuery');
// Execute the function and return the data
func(function (returnData) {
callback(returnData)
});
}
// ********************************
// NEW VERSION ATTEMPTING TO USE 'vm' SANDBOXING.
// ********************************
import Query = require("query");
var vm = require("vm");
export function executeDynamicScriptOnServer(javaScript, callback) {
// Load the module with the dyanamic script.
vm.runInNewContext(javaScript, vm.createContext({ Query: Query.Query }));
// ---- > NOT SURE HOW TO EXECUTE THE 'QueryLib.onQuery" FUNCTION IN THE INJECTED JAVASCRIPT.
func(function (returnData) {
callback(returnData)
});
}
我相信这应该可以满足您的需求:
// ********************************
// NEW VERSION ATTEMPTING TO USE 'vm' SANDBOXING.
// ********************************
var Query = require("query");
var vm = require("vm");
export function executeDynamicScriptOnServer(javaScript, callback) {
javaScript += 'onQuery(done)'
// Load the module with the dyanamic script.
vm.runInNewContext(javaScript, vm.createContext({
Query: Query.Query,
done: function(returnData) {
// do stuff with the result
callback(returnData)
}
}));
}
我们正在为我们的 REST 端点使用 Loopback,并且有一个端点从数据库中提取 JavaScript,然后使用 eval 在 Node 实例的服务器上加载和执行特定功能。我们想转换为 Node 的 VM 功能,但是 运行 遇到了问题。具体怎么做:
- 在 'namespace', 中加载具有多种功能的代码
- 执行其中一项功能,
- 允许注入的函数访问导入的模块,
- 然后 return 该函数的结果。
基于 'eval' 的代码运行良好,但似乎已停止使用最新的 Node.因此,我们利用这个机会转换为 Node 的 'vm' 沙盒。但是,我们无法调用嵌入在命名空间中的函数。
// ********************************
// CODE TO CALL THE SERVER END-POINT AND CONSUME THE RETURN
// ********************************
let javaScriptCode = `
namespace QueryLib {
// Execute a query.
export function onQuery(callback) {
// Execute the Query functions from the 'Query' import to retrieve data.
Query.select('RowID', 'CustomerID', 'Name').from('customer').then(function (e, rows) {
callback(e, rows)
})
}
}
`
// Call the end-point and receive the query data.
ServerRestEndPoints.executeDynamicScriptOnServer(javaScriptCode, function (data) {
// Process 'data' here.
});
// ****************************************************************
// SERVER (END-POINT) CODE
// ****************************************************************
// ********************************
// CURRENT VERION USING 'EVAL'
// ********************************
import Query = require("query");
export function executeDynamicScriptOnServer(javaScript, callback) {
// Load the module with the script passed in (pulled from the db).
eval(javaScript);
// Load the function from the dynamic script
let func = eval('onQuery');
// Execute the function and return the data
func(function (returnData) {
callback(returnData)
});
}
// ********************************
// NEW VERSION ATTEMPTING TO USE 'vm' SANDBOXING.
// ********************************
import Query = require("query");
var vm = require("vm");
export function executeDynamicScriptOnServer(javaScript, callback) {
// Load the module with the dyanamic script.
vm.runInNewContext(javaScript, vm.createContext({ Query: Query.Query }));
// ---- > NOT SURE HOW TO EXECUTE THE 'QueryLib.onQuery" FUNCTION IN THE INJECTED JAVASCRIPT.
func(function (returnData) {
callback(returnData)
});
}
我相信这应该可以满足您的需求:
// ********************************
// NEW VERSION ATTEMPTING TO USE 'vm' SANDBOXING.
// ********************************
var Query = require("query");
var vm = require("vm");
export function executeDynamicScriptOnServer(javaScript, callback) {
javaScript += 'onQuery(done)'
// Load the module with the dyanamic script.
vm.runInNewContext(javaScript, vm.createContext({
Query: Query.Query,
done: function(returnData) {
// do stuff with the result
callback(returnData)
}
}));
}