0

I have a situation in which I have to use eval in Javascript. Yes, I know it is evil, but in this case it is required, because two requisites:

  1. The Javascript code is big.
  2. It has to be evaluated (and downloaded) only in a few situations, so I don't want the script to be downloaded always, but on demand.

With these requisites, I have written an XMLHttpRequest to request the code (600+K), and I want to eval that code to take place immediately. As I'll show later, the script contains just data to be inserted in two variables. The problem is that evaluating this javascript fails always with syntax error. If I put the code verbatim (without eval), the code executes fine. This is the minimal example. I have a search.js file like this:

// search.js for functional mind. Generated statically
// from the set of posts.
posts = { 'postlist' : ['<a href="XXX">YYY</a>', 'other link...' ] };
posts_for_word = { 'word1' : [0,1], 'word2' : [Z,K] }; 

The last variable, posts_for_word includes indexes of posts containing that word. The problem comes when I evaluate that Javascript inside eval:

// global environment
var posts = {}; // Initial value, empty
var posts_for_word = {}; // same

function() {
var request = // create XMLHTTPREQUEST request
var response = // obtain response (the javascript)
eval( response ); // <- syntax error
// access posts or posts_for_word
posts.postlist[ posts_for_word['word1'][0] ]
....
}

The problems:

  1. When I evaluate the javascript shown above with eval, firefox tells me that it is bad formed in the first line.
  2. I then removed the comments. I supposed that eval would evaluate it as if it was a normal Javascript program, but it doesn't seem to accept comments (why?).
  3. After removing the comments, the code works, but still the Javascript console of Firefox tells me that there is a syntax error in the first line (that defining the JSON first variable). Why?
Diego Sevilla
  • 28,636
  • 4
  • 59
  • 87
  • The usual way to load javascript when needed is to insert a new script tag into the DOM. Is there a reason why this won't work in your case? – cobbal Oct 06 '11 at 21:49
  • @cobbal, I tried that first. I may have done something wrong at that moment. I'll try it again, but it didn't work (I inserted the script, but the variables could not be found in the next javascript line). Anyway, the questions for `eval` are still open. – Diego Sevilla Oct 06 '11 at 21:52

1 Answers1

4

You shouldn't use AJAX and eval() to make a script happen on your website, instead, create a <script> element with a link to the file and append it to the body:

(function() {
    var jsCode = document.createElement('script');
    jsCode.setAttribute('src', 'http://localhost/tests/doStuff.js');
    document.body.appendChild(jsCode);
}());

(This code is actually taken directly from a bookmarklet of mine, and it does the trick nicely.)

As for the variable scope, if you declare them as var variable in your inner file, it would override the file scope and become global.


However, should you require a synchronous load of a script, you will have to (despite the fact it is considered bad practice) to use a synchronous AJAX call. How to do that was already written before me, Dynamically loading JavaScript synchronously

Community
  • 1
  • 1
Madara's Ghost
  • 172,118
  • 50
  • 264
  • 308
  • Thanks, Rikudo Sennin. I also tried that option. The problem is that this script is retrieved *asynchronously*, and the line just following that dynamic DOM manipulation *don't see* the new variable. It seems that as the code is big, it takes long to load, and Firefox always does this asynchronously. The result: the line just after that code don't find the variable. After some time, I try again, and the variable *is* there. Now, even if I add the `jsCode.setAttribute('async', '');`, the script is loaded asynchronously. – Diego Sevilla Oct 06 '11 at 22:25
  • Take a look in this question: http://stackoverflow.com/questions/2879509/dynamically-loading-javascript-synchronously – Madara's Ghost Oct 06 '11 at 22:29
  • now that makes much more sense. Let me try it (and thanks for the pointer!) – Diego Sevilla Oct 06 '11 at 22:34
  • No problem. Added to my answer for future user reference. – Madara's Ghost Oct 06 '11 at 22:37
  • 1
    It works, actually. Thanks! I know synchronously loading may be considered bad practice, but what to do if I need the values to be there and want to load them on demand? I will accept your answer in some days. I still leave it open because I really would know why `eval` is not supporting comments. Also, I'm getting syntax errors even when the script works... – Diego Sevilla Oct 06 '11 at 22:39