使用封闭函数将 Eval 转换为 Node 的 VM 模块

Converting Eval to Node's VM Module with an Enclosed Function

我们正在为我们的 REST 端点使用 Loopback,并且有一个端点从数据库中提取 JavaScript,然后使用 eval 在 Node 实例的服务器上加载和执行特定功能。我们想转换为 Node 的 VM 功能,但是 运行 遇到了问题。具体怎么做:

  1. 在 'namespace',
  2. 中加载具有多种功能的代码
  3. 执行其中一项功能,
  4. 允许注入的函数访问导入的模块,
  5. 然后 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)
    }
  }));
}