简体   繁体   English

如何从 Node.js 中的 URL 请求

[英]how to require from URL in Node.js

Is there a standard way to require a Node module located at some URL (not on the local filesystem)?是否有一种标准的方法来要求位于某个 URL(不在本地文件系统上)的 Node 模块?

Something like:就像是:

require('http://example.com/nodejsmodules/myModule.js');

Currently, I am simply fetching the file into a temporary file, and requiring that.目前,我只是将文件提取到一个临时文件中,并要求这样做。

You can fetch module using http.get method and execute it in the sandbox using vm module methods runInThisContext and runInNewContext .您可以使用http.get方法获取模块并使用vm模块方法runInThisContextrunInNewContext在沙箱中执行它。

Example例子

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');
    }));
});

IMO, execution of the remote code inside server application runtime may be reasonable in the case without alternatives. IMO,在没有替代方案的情况下,在服务器应用程序运行时内执行远程代码可能是合理的。 And only if you trust to the remote service and the network between.并且仅当您信任远程服务和网络之间的关系时。

Install the module first :首先安装模块:

npm install require-from-url

And then put in your file :然后放入你的文件:

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

0 dependency version (node 6+ required, you can simply change it back to ES5) 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); });
        }
    });
});

It is still the asynchronous version, if sync load is the case, a sync http request module for example should be required它仍然是异步版本,如果是同步负载,则需要例如sync http request module

If you want something more like require , you can do this:如果你想要更像require东西,你可以这样做:

var http = require('http')
  , vm = require('vm')
  , concat = require('concat-stream') 
  , async = require('async'); 

function http_require(url, callback) {
  http.get(url, function(res) {
    // console.log('fetching: ' + url)
    res.setEncoding('utf8');
    res.pipe(concat({encoding: 'string'}, function(data) {
      callback(null, vm.runInThisContext(data));
    }));
  })
}

urls = [
  'http://example.com/nodejsmodules/myModule1.js',
  'http://example.com/nodejsmodules/myModule2.js',
  'http://example.com/nodejsmodules/myModule3.js',
]

async.map(urls, http_require, function(err, results) {
  // `results` is an array of values returned by `runInThisContext`
  // the rest of your program logic
});

You could overwrite the default require handler for .js files:您可以覆盖 .js 文件的默认 require 处理程序:

require.extensions['.js'] = function (module, filename) {
    // ...
}

You might want to checkout better-require as it does pretty much this for many file formats.您可能想要结帐更好-需要,因为它对许多文件格式几乎都这样做。 (I wrote it) (我写的)


  const localeSrc = 'https://www.trip.com/m/i18n/100012631/zh-HK.js';
  const http = require('http');
  const vm = require('vm');
  const concat = require('concat-stream');
  http.get(
    localeSrc,
    res => {
      res.setEncoding('utf8');
      res.pipe(
        concat({ encoding: 'string' }, remoteSrc => {
          let context = {};
          const script = new vm.Script(remoteSrc);
          script.runInNewContext(context);
          console.log(context);
        }),
      );
    },
    err => {
      console.log('err', err);
    },
  );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM