node.js 可以像 CouchApp 一样执行从 CouchDB 提取的 JavaScript 函数吗?如何?

Posted

技术标签:

【中文标题】node.js 可以像 CouchApp 一样执行从 CouchDB 提取的 JavaScript 函数吗?如何?【英文标题】:Can node.js execute JavaScript functions pulled from CouchDB like CouchApp does? How? 【发布时间】:2010-09-15 20:18:15 【问题描述】:

快速概述是这样的:对于我的 Web 应用程序,我可以使用 CouchApp 和 CouchDB 视图等编写大部分功能。我喜欢 CouchApp 的功能,它通过复制将我的代码推送到服务器 - 这使得部署周期好简单。

但是,为了做一些 couchdb 不支持的任意工作并解决一些限制,我需要在 CouchDB 前面放置一个 Web 平台。我正在考虑在 node.js 中构建它,因为它使用 javascript,我想继续将代码推送到数据库的简单部署方法。

这是我想象它的工作方式: - 我使用普通方法和 node 命令在 node.js 中编写一个 Web 服务器/服务来启动它。 - 此服务连接到沙发数据库并获取虚拟列表和 URL 映射列表。此列表存储在 redis 中,以便快速查找。该列表将根据主机和路径等告诉服务器,当它收到请求时,要运行哪个处理程序。 - 服务器获取处理程序 - 这只是一个文档,它可以是设计文档或 couchdb 中的任意 json 文档。然后执行该处理程序来处理请求,就好像我将处理程序编写为节点 js 的一部分一样。

那么问题来了,如何以文本形式获取一个包含 JavaScript 函数的子数据结构,并执行该函数?

这可能很明显,但我来自编译背景,所以通常这里会有一个编译步骤,这使得这几乎不可能。

所以,我在想的是伪代码: var string thecode = getValueForMapKey(handlerFunctionIWant); 莫名其妙地执行(代码)

是否有一个 exec 或 run 函数可以在 JavaScript 中执行上述神奇的执行步骤?

【问题讨论】:

有趣的想法——即时从 couchdb 中提取代码——你是否曾经这样做过? 我看到人们成功地做到了这一点。使用这种技术,您可以同时部署 CouchDB 和 Node.js 升级。 通常如果 javascript 没有改变,你将代码放在 _attachments/script 并使用<script src="…"></script> 加载它。如果它发生变化,您可以创建一个普通文档(在设计文档之外),并使用脚本标签来获取它。要成为动态的,您可以加载多个文件并只执行您需要的一个。只做 ajax、eval、db.get 等,如果必须的话。 【参考方案1】:

它将在 node.js 上下文中运行。

你也可以在节点中使用它,像这样,作为一个动态函数:

var cradle = require('cradle');
var db = new(cradle.Connection)().database('db_name');

db.get('_design/node%2Fyour_code', function (err, doc) 
  if (!err)
    var your_code = new Function(doc['arguments'].join(','), doc.code);
    your_code("cool", "also cool");
  else
    console.error('error:', err);
  
);

让您的文档看起来像这样:


   "_id": "_design/node/your_code",
   "arguments": [
       "nameOfArg1",
       "nameOfArg2"
   ],
   "code": "console.log('arg1', nameOfArg1); console.log('arg2', nameOfArg2);"

它与调用新函数的范围相同,因此您可以访问 cradle,或者您可以要求其他库,这些库将被加载,就好像它是该范围内的 anon 函数一样。

将其放入设计文档中,然后只有管理员可以进行更改,开箱即用。

这是一个更好但类似的方法:

// Format, in db:
doc = 
   "_id": "_design/node",
   "your_function_name": 
       "arguments": [
           "nameOfArg1",
           "nameOfArg2"
       ],
       "code": "console.log('arg1', nameOfArg1); console.log('arg2', nameOfArg2);"
   ,
   "your_other_function_name": 
       "arguments": [
           "name"
       ],
       "code": "console.log('hello', name, 'how\\'s it going, bro?');"
   
;


var cradle = require('cradle');
var db = new(cradle.Connection)().database('db_name');

function run_from_db(name, args)
  db.get('_design/node', function (err, doc) 
    if (!err)
      if (doc[name] !== undefined)
        var fn = new Function(doc[name]['arguments'].join(','), doc[name].code);
        fn.apply(fn, args);
      else
        console.error("could not find", name, "in _design/node");
      
    else
      console.error(err);
    
  );



run_from_db('your_other_function_name', ['konsumer']);

这将输出:

hello konsumer how's it going, bro?

【讨论】:

【参考方案2】:

eval(handlerFunctionIwant) 是执行它的调用。当然,您需要确保黑客无法将代码注入该字符串。

我不清楚这是否会在可以访问其他 javescript 资源(例如 node.js 的其余部分或访问您的 couchdb 库)的上下文中对其进行评估。

【讨论】:

以上是关于node.js 可以像 CouchApp 一样执行从 CouchDB 提取的 JavaScript 函数吗?如何?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 CouchDB 中提取 CouchApp

如何使用本机反应像 Node.js 一样获取`__dirname`

如何使用 Node.js net.Socket 与 Postgresql 数据库进行通信,就像使用终端一样

如何像使用 PHP 一样在我的 HTML 页面中运行 Node.js 脚本?

从 CouchApp 发布数据库视图

node.js 如何决定一个语句是不是被异步处理?