【问题标题】:Serve dynamic javascript file with nodejs使用 nodejs 提供动态 javascript 文件
【发布时间】:2014-11-23 12:22:03
【问题描述】:

问题

如何动态提供 javascript 文件?具体来说,脚本保留了它的大部分主体,但有一些变量是可变的(想象一下 HTML Jade 模板,但这是针对纯 javascript 的)。

场景

当用户或浏览器(一般为http GET)访问/file.js时传递参数api,例如/file.js?api=123456,我想输出纯 javascript,我可以将 123456 动态地放入我的代码中。 Content-Type 是application/javascript

示例:

var api = #{req.query.api}; //Pseudo
//The rest of my javascripts template
...

从我的主 .js 文件中,我已经设置了路线:

app.get( '/file.js', function( req, res ) {

    //Pseudo code that I would like to achieve
    var name = req.query.name;
    res.render( 'out_put_javascript_file_from_jade_file.jade', { name: name } );

});

所以当一个人访问/file.js时,脚本文件会根据URL中传入的参数api进行不同的渲染。我能想到的唯一可能的动态方式是使用 Jade,但它不允许纯 JavaScript 模板。我相信一定有其他解决方案。

请原谅我的解释。问题有点像这样:How to generate a pure JavaScript file with Jade

【问题讨论】:

  • 嗯,动态生成JS有点危险?为什么需要这样的功能?您可以调用 my_common.js 并在您的 JADE 模板中生成 inline JS。这个内联 JS 将是唯一改变的 JS。但是如果没有更多信息,很难给出建议:)
  • 我正在编写一个小的 API sn-p,但它需要从 javascript 文件中的数据库生成 API 密钥。使用 PHP 相当容易,但我有很多关于 NodeJS 的知识要学习。可以这样想象:用户访问http://example.com/file.js?api=123,浏览器返回application/javascript,代码如下alert( 'Your API key is 123' );。任何方法都应该有效,但我有限的知识并没有提出任何足够聪明的方法。请指教。
  • Jade 是一个 HTML 模板引擎。你试图解释什么是没有意义的。为什么需要生成JS文件?您真的不想生成alert()?那么告诉我们你想对生成的输出做什么?谁处理它/正在处理它?
  • Jade 正是我想出的,因为我没有其他解决方案。我相信有更好的解决方案。 alert() 只是伪代码。我希望在访问路线时这样做,例如/file.js?api=123,浏览器将输出纯javascript代码,其中一部分是动态生成的。伪:http.get /file.js?api=123 将产生 api = 123; do_something_with_that_api(); 或 http.get file.js?api=456 将产生 api = 456; do_something_with_that_api();

标签: javascript node.js templates express pug


【解决方案1】:

如果你想做一些快速而肮脏的事情,那么你可以做这样的事情(基于你在 cmets 中的例子)。

App init - 读取 .js 模板 文件并缓存它:

// this should be async, but hey, not teaching you that part here yet
var fileJs = fs.readFileSync('file.js.template');

文件.js:

(function() {
  $(window).on('load', function() {
    alert('Your api key is API_KEY_CONST');
  });
})();

请求:

GET /api/file.js?key=123

路由器:

app.get('/api/file.js', function(req, res) {

    var key = req.query.key;
    var key = fetchKeyFromDBSync(); // just to make it easier here, no async.
    var out = fileJs.replace(API_KEY_CONST, key);

    res.setHeader('content-type', 'text/javascript');
    res.write(out);
    res.end();
});

现在,这真的很愚蠢,你不应该在家里尝试,但它只是展示了如何做你想做的事。

编辑:

根据文件长度,如果将文件的块放入数组中,可能会更好一些,例如:

var fileChunks = ['(function(){ blablabla;', 'var myAPIKey=', 'KEY_PLACEHOLDER', '; alert (myAPIKey);', '})()']

所以稍后当您使用真正的 API 密钥解决它时,您可以加入该文件。

fileChunks[2] = '12345';
var responseData = fileChunks.join('');
res.write(responseData);

但是您最后访问的 api 密钥会保存在一个数组中。不完全是未来的证明,但如果你需要快速的东西,它应该可以工作。

【讨论】:

  • 哇!这非常快,而且确实很脏,哈哈。但它确实适用于我的要求!我有一个简单的问题,fileJS.replace() 真的是String.prototype.replace 吗?我只是想知道如何正确使用它!而且,一点也不傻。我不会在家里尝试。如果没有可能的解决方案,我会将其投入生产。我在这里没有看到任何安全问题。
  • 是的,fileJS.replace 正在对 readFileSync 的结果执行此操作(它会返回文件的内容,所以如果它是二进制文件...)无论如何,理想情况下,您应该懒惰地加载这些文件而不提供服务直到它们准备好(这可能是您的服务器启动后的几毫秒)。您也可以这样做:将文件内容作为流读取,并制作一个转换流以放在请求和响应之间。只要它没有看到常量(CAPS),Transformer 就会将数据输出到 res。当它遇到上限时,它会暂停写入和缓冲输入,直到它读取并替换常量,然后通过管道输出。
  • 第一种方法只缓存文件内容一次。流每次都读取文件。看你需要什么。
  • 我怀疑为什么这是一种愚蠢的做事方式?也许它不安全,但除了 URL 欺骗之外,我想不出任何东西。服务器端验证不能摆脱任何类型的攻击吗?
  • 嗯,感觉很臭,我相信有更好的方法。至于安全性,我什至没有谈论这方面。您对此有什么具体问题吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-25
  • 1970-01-01
  • 2021-09-07
  • 2011-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多