如何从Node.js中的URL要求

33 javascript node.js

是否有一种标准方法要求Node模块位于某个URL(而不是本地文件系统)?

就像是:

require('http://example.com/nodejsmodules/myModule.js');
Run Code Online (Sandbox Code Playgroud)

目前,我只是将文件提取到一个临时文件中,并要求它.

Phi*_*lev 31

您可以使用http.get方法获取模块,并使用vm模块方法runInThisContextrunInNewContext在沙箱中执行它.

var http = require('http')
  , vm = require('vm')
  , concat = require('concat-stream'); // this is just a helper to receive the
                                       // http payload in a single callback
                                       // see https://www.npmjs.com/package/concat-stream

http.get({
    host: 'example.com', 
    port: 80, 
    path: '/hello.js'
  }, 
  function(res) {
    res.setEncoding('utf8');
    res.pipe(concat({ encoding: 'string' }, function(remoteSrc) {
      vm.runInThisContext(remoteSrc, 'remote_modules/hello.js');
    }));
});
Run Code Online (Sandbox Code Playgroud)

IMO,在没有替代方案的情况下,在服务器应用程序运行时内执行远程代码可能是合理的.只有当你信任远程服务和网络之间时.

  • 1.也许代码可以通过HTTPS在广泛信任的CDN中或通过可信赖的合作伙伴获得.2.也许代码可以通过HTTPS在远程内部位置获得.3.也许代码是在内部打包和分发的,这样就可以阻止访问最终执行它的FS,因此不能使用npm.这些只是我的头脑; 也许他们不是很好的理由,但他们是理由.无论如何,我的观点很简单,解释一个意见的理由比将其标记为"不良实践"更具有用,并且不再多说.您现在的评论是什么! (9认同)
  • 在这个时代,HTTP-GET应该被认为是一种非常有效的引用/打开文件的方法.暗示文件在某种程度上更安全​​,因为你首先将它们发送到本地硬盘驱动器,这非常类似于通过默默无闻的安全性.文件的可信度不应仅仅通过是否通过FILE://或HTTPS访问来测量?:// (9认同)
  • 感谢你的回答。至于“执行远程代码”;如今,大多数节点应用程序都是通过从网络获取的“npm install”进行初始化的。这与OP在精神上寻求做的事情有什么不同?一般来说,这个想法并没有什么不好的做法,但任何事情都可能做得很糟糕;造成安全风险。我希望做这件事来管理我的配置脚本(它不仅仅是 json,因为它需要更多的智能)并且我有轮换密钥来保护请求,除了应用程序之外没有人知道(更安全)比 npm 模块)。 (3认同)
  • 我对这些信息表示支持,但我确实希望您能费心解释*为什么*,而不是仅仅说“这真的很糟糕”。 (2认同)
  • 因此,在生产应用程序中不需要来自“github”的任何内容;) (2认同)

小智 8

首先安装模块:

npm install require-from-url
Run Code Online (Sandbox Code Playgroud)

然后放入你的文件:

var requireFromUrl = require('require-from-url/sync');
requireFromUrl("http://example.com/nodejsmodules/myModule.js");
Run Code Online (Sandbox Code Playgroud)


Wil*_*ung 6

0 依赖版本(需要节点 6+,您可以简单地将其改回 ES5)

const http = require('http'), vm = require('vm');

['http://example.com/nodejsmodules/myModule.js'].forEach(url => {
    http.get(url, res => {
        if (res.statusCode === 200 && /^text\/javascript/.test(res.headers['content-type'])) {
            let rawData = '';
            res.setEncoding('utf8');
            res.on('data', chunk => { rawData += chunk; });
            res.on('end', () => { vm.runInThisContext(rawData, url); });
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

它仍然是异步版本,如果是同步负载,则需要sync http request module 例如