Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serve dynamic javascript file with nodejs

Questions

How to serve javascript file dynamically? Specifically, the scripts maintain most of its body but with some variables changable (imagine HTML Jade template, but this is for pure javascript).

Scenario

When user or browser (http GET in general) visits /file.js passing parameter api, e.g. /file.js?api=123456, I would like to output pure javascript where I can take that 123456 and put in inside of my code, dynamically. Content-Type is application/javascript.

Sample:

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

From my main .js file, I have set up the route:

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

});

So when a person visits /file.js, the script file will be rendered differently based on the parameter api passed in the URL. The only possible dynamic way I can think of is using Jade, but it doesn't allow pure javascript template. I believe there must be other solutions.

Please excuse my explanation. The problem is somewhat like this: How to generate a pure JavaScript file with Jade

like image 759
cuzmAZN Avatar asked Sep 29 '14 07:09

cuzmAZN


1 Answers

If you want to do something quick and dirty, then you can do something like this (based on your example in the comments).

App init - read the .js template file and cache it:

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

File.js:

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

Request:

GET /api/file.js?key=123

Router:

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

Now, this is really dumb and you should not try it at home, but it simply demonstrates how to do what you wanted.

Edit:

Depending on the file length, you might perform a bit better if you put the chunks of the file into an array, like:

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

So later when you're resolving it with the real API key, you join the file.

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

But your last-accessed api key is then held in an array. Not quite future proof, but it shouls work if you need something quick.

like image 107
Zlatko Avatar answered Oct 04 '22 06:10

Zlatko