有没有一种标准的方法可以要求在某个URL上(而不是本地文件系统上)定位的Node模块?
就像这样:
require('http://example.com/nodejsmodules/myModule.js');
目前,我只是将文件获取到一个临时文件中,并进行引用。
有没有一种标准的方法可以要求在某个URL上(而不是本地文件系统上)定位的Node模块?
就像这样:
require('http://example.com/nodejsmodules/myModule.js');
目前,我只是将文件获取到一个临时文件中,并进行引用。
示例
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');
}));
});
在没有其他选择的情况下,我认为在服务器应用程序运行时执行远程代码可能是合理的,只有当您信任远程服务和网络连接时才这样做。
wget
下载到本地硬盘再访问会使文件更加安全,这种方法与仅仅依赖于难以理解的安全性原则很相似。一个文件的可信度不应仅仅基于你是通过 FILE:// 还是 HTTPS?:// 访问它来衡量。 - Már Örlygssonnpm install
初始化的,该命令从Web上拉取依赖包。这与OP所寻求的精神有何不同?总的来说,这个想法本身并没有什么不好的实践,但任何事情都可能做得很糟糕,从而产生安全风险。就我个人而言,我正在寻求使用此方法来管理我的配置脚本(它不仅仅是JSON,还需要更多的智能化),并且我已经设置了轮换密钥以保护请求,只有应用程序才知道(比npm模块更安全)。 - rainabba首先安装该模块:
npm install require-from-url
然后将其放入您的文件中:
var requireFromUrl = require('require-from-url/sync');
requireFromUrl("http://example.com/nodejsmodules/myModule.js");
0依赖版本(需要node 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 && /\/javascript/.test(res.headers['content-type'])) {
let rawData = '';
res.setEncoding('utf8');
res.on('data', chunk => { rawData += chunk; });
res.on('end', () => { vm.runInThisContext(rawData, url); });
}
});
});
如果需要同步加载的话,仍然是异步版本。例如,可以使用 sync-request 这个同步的http请求模块。
if (res.statusCode === 200 && /^application\/javascript/.test(res.headers['content-type']))
中使用 'application/javascript' 而不是 'text/javascript'。 - Paul Verschoorrequire
的功能,可以使用以下方法: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
});
您可以覆盖默认的.js文件require处理程序:
require.extensions['.js'] = function (module, filename) {
// ...
}
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);
},
);