Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #28709 > unrolled thread

alternatives to eval() for this case

Started byJay Braun <lyngwyst@gmail.com>
First post2015-09-25 10:26 -0700
Last post2015-09-27 07:45 -0700
Articles 8 — 5 participants

Back to article view | Back to comp.lang.javascript


Contents

  alternatives to eval() for this case Jay Braun <lyngwyst@gmail.com> - 2015-09-25 10:26 -0700
    Re: alternatives to eval() for this case Danny <dann90038@gmail.com> - 2015-09-25 15:39 -0700
      Re: alternatives to eval() for this case Jay Braun <lyngwyst@gmail.com> - 2015-09-25 15:50 -0700
    Re: alternatives to eval() for this case Joao Rodrigues <groups_jr-1@yahoo.com.br> - 2015-09-26 00:35 -0300
      Re: alternatives to eval() for this case Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2015-09-26 09:33 +0200
    Re: alternatives to eval() for this case Jay Braun <lyngwyst@gmail.com> - 2015-09-26 20:14 -0700
      Re: alternatives to eval() for this case Martin Honnen <mahotrash@yahoo.de> - 2015-09-27 10:30 +0200
        Re: alternatives to eval() for this case Jay Braun <lyngwyst@gmail.com> - 2015-09-27 07:45 -0700

#28709 — alternatives to eval() for this case

FromJay Braun <lyngwyst@gmail.com>
Date2015-09-25 10:26 -0700
Subjectalternatives to eval() for this case
Message-ID<1a8362bb-6ff2-41a9-93b2-5469b67ffd02@googlegroups.com>
Hello.  I have read much of the on-line material about the drawbacks of eval().  One of the few cases where eval() seems to be regarded as acceptable is an AJAX case like this, where a script on the server side is being requested:

function evalRequest(url) {
     var xmlhttp = new XMLHttpRequest();
     xmlhttp.open("GET", filename);
     //perhaps set request header
     xmlhttp.send();
     xmlhttp.onreadystatechange = function() {
          if (xmlhttp.readyState==4 && xmlhttp.status==200) {
               eval(xmlhttp.responseText);
          }
     }
     xmlhttp.open("GET", url, true);
     xmlhttp.send(null);
 }

which is exactly the type of case where I am using it.  It works great when the requested script is "reasonably" sized, e.g., tens of KB.  But occasionally, the server-side application processes so much data that the file might be tens of MB in length.  eval() is not only slow (as expected), but does not complete the parsing of the file.

One alternative is to break up the script into smaller pieces when necessary.  I would like to avoid that.

The file is not in JSON notation, so I cannot use JSON.parse().  

I have read about jQuery.getScript(), but it was not clear to me which parts of the above need to be re-cast.  I cannot simply replace eval() with $.getScript(), can I? (I tried this, and the answer is No; a link to a full discussion would be appreciated.)

Perhaps there are some other alternatives.  Can a script be "compiled" on the server side, and the resulting binary requested?  Or might there be a third-party tool that simply replaces eval() for heavy-duty requirements like this?

Thank you,
Jay

[toc] | [next] | [standalone]


#28714

FromDanny <dann90038@gmail.com>
Date2015-09-25 15:39 -0700
Message-ID<8e47dbe1-4b98-4041-bbc4-55e646a33f90@googlegroups.com>
In reply to#28709
to Jay Braun

seems to me that
xmlhttp.open("GET", filename);   // getting the file

and then you grab the output from .responseText
incidentally, the output is js, not json though
well, if the output is js, then why not just 
dump the output in a "script" element?
--------------------------------------
function evalRequest(url){
		var s = document.createElement("script");
		s.src = filename; // whatever filename is, assuming a variable
		document.head.appendChild(s);
	
}

[toc] | [prev] | [next] | [standalone]


#28715

FromJay Braun <lyngwyst@gmail.com>
Date2015-09-25 15:50 -0700
Message-ID<cbfb06a4-d42e-488f-bde8-50f8207d6a9b@googlegroups.com>
In reply to#28714
> function evalRequest(url){
> 		var s = document.createElement("script");
> 		s.src = filename; // whatever filename is, assuming a variable
> 		document.head.appendChild(s);
> 	
> }

Looks very promising.  I return to work on Wednesday, and will try this.

Thank you,
Jay

[toc] | [prev] | [next] | [standalone]


#28717

FromJoao Rodrigues <groups_jr-1@yahoo.com.br>
Date2015-09-26 00:35 -0300
Message-ID<mu53pe$ktl$1@speranza.aioe.org>
In reply to#28709
On 25/09/15 14:26, Jay Braun wrote:
> Hello.  I have read much of the on-line material about the drawbacks
> of eval().

eval() isn’t evil, just misunderstood

<http://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/>


> One of the few cases where eval() seems to be regarded as
> acceptable is an AJAX case like this, where a script on the server
> side is being requested:

There are other ways to insert a script into a document than using AJAX

>
> function evalRequest(url) {
>   var xmlhttp = new XMLHttpRequest();
>   xmlhttp.open("GET", filename); //perhaps set request header
>   xmlhttp.send();
>   xmlhttp.onreadystatechange = function() {
>     if (xmlhttp.readyState==4 && xmlhttp.status==200) {

Here you might check the Content-Type to be sure of the file type, e.g.

var rsp, contentType = xhr.getResponseHeader("Content-Type");
if (/json|javascript/i.test(contentType)) {
   rsp = xhr.responseText;
   // Or use JSON.parse if it is a JSON file
}
// use a callback function passed to evalRequest() to do the job
// (insert the script):
insertScript(rsp, 'newJS');

>     }
>   }
>   xmlhttp.open("GET", url, true);
>   xmlhttp.send(null);
> }
>

Example of such a callback function:

function insertScript(src, id) {
   var script = document.createElement('script');
   script.src = src;
   script.async = false; // HTML5
   document.head.appendChild(script);
}

> which is exactly the type of case where I am using it.  It works
> great when the requested script is "reasonably" sized, e.g., tens of
> KB.  But occasionally, the server-side application processes so much
> data that the file might be tens of MB in length.  eval() is not only
> slow (as expected), but does not complete the parsing of the file.

I can't imagine a script file so big...

The problem, I think, is if you need the scripts to execute in an 
expected order. If so, you may try to mark the downloaded script as not 
async [1], using:

script.async = false;

[1] <http://caniuse.com/#feat=script-async>


-- 
Joao Rodrigues

[toc] | [prev] | [next] | [standalone]


#28720

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2015-09-26 09:33 +0200
Message-ID<360817097.BH5zBMaEkf@PointedEars.de>
In reply to#28717
Joao Rodrigues wrote:

> On 25/09/15 14:26, Jay Braun wrote:
>> One of the few cases where eval() seems to be regarded as
>> acceptable is an AJAX case like this, where a script on the server
>> side is being requested:
> 
> There are other ways to insert a script into a document than using AJAX

More importantly, there are a lot *better* ways to do that.  One problem is 
that this does not work well in strict mode, where the eval scope chain is 
empty, and it does not work cross-origin without CORS.

> The problem, I think, is if you need the scripts to execute in an
> expected order. If so, you may try to mark the downloaded script as not
> async [1], using:
> 
> script.async = false;
> 
> [1] <http://caniuse.com/#feat=script-async>

If you read more carefully, you will realize that this does not work.  
“async=false” not only requires HTML5 support, but it is the *default* 
there:

<https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#Attributes> pp.

For scripts to be *executed* in a specific *order*, you need a promise-based 
approach like requireJS, where you define() the dependencies of a module, 
then require() it, and only when it has become available you (automagically) 
execute the code that depends on it.

<http://requirejs.org/>

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#28740

FromJay Braun <lyngwyst@gmail.com>
Date2015-09-26 20:14 -0700
Message-ID<1b5a10d5-b323-4b6a-a9e2-e49979dfe502@googlegroups.com>
In reply to#28709
> I can't imagine a script file so big... 

I'll try to keep this short (unlike my script :-)).

We are investigating the use of a browser to replace a legacy GUI for a legacy simulation model.  The model can conceivably store about 100K objects at any given time.  It might begin a scenario with a few thousand objects, then have tens of thousands added to the scenario all at once.

Each object's graphical representation typically consists of at least 4 different SVG elements:  a basic shape like a square or circle, one or more additional lines, dots, etc., to distinguish the object's role more specifically, a line indicating speed and course, and an ID.  I chose SVG over Canvas because of its scalability and because of some capabilities provided by the DOM.

I generate JavaScript scripts periodically with a C program on the server side that accesses a database updated by the simulation.  The C program doesn't break a sweat writing the JavaScript.  I am *not* dumping the whole database every time, but at certain junctures, many objects might be added to the scenario all at the same time.

If anyone here thinks I'm barking up the wrong tree (or down the wrong DOM), I welcome your comments at this early stage.

Thanks for your posts,
Jay

[toc] | [prev] | [next] | [standalone]


#28742

FromMartin Honnen <mahotrash@yahoo.de>
Date2015-09-27 10:30 +0200
Message-ID<mu89el$78e$1@news.albasani.net>
In reply to#28740
Jay Braun wrote:

> We are investigating the use of a browser to replace a legacy GUI for a legacy simulation model.  The model can conceivably store about 100K objects at any given time.  It might begin a scenario with a few thousand objects, then have tens of thousands added to the scenario all at once.
>
> Each object's graphical representation typically consists of at least 4 different SVG elements:  a basic shape like a square or circle, one or more additional lines, dots, etc., to distinguish the object's role more specifically, a line indicating speed and course, and an ID.  I chose SVG over Canvas because of its scalability and because of some capabilities provided by the DOM.
>
> I generate JavaScript scripts periodically with a C program on the server side that accesses a database updated by the simulation.  The C program doesn't break a sweat writing the JavaScript.  I am *not* dumping the whole database every time, but at certain junctures, many objects might be added to the scenario all at the same time.
>
> If anyone here thinks I'm barking up the wrong tree (or down the wrong DOM), I welcome your comments at this early stage.


Do you generate Javascript code that then creates SVG elements? As an 
alternative approach you could try to have the server-side code generate 
the SVG snippets and load them with XMLHttpRequest and insert them into 
the DOM tree. Loading XML (and SVG is XML) is what XMLHttpRequest was 
originally designed for.

I can't tell whether that performs better than creating Javascript 
script code that generates SVG elements but it sounds like a cleaner 
approach.

[toc] | [prev] | [next] | [standalone]


#28745

FromJay Braun <lyngwyst@gmail.com>
Date2015-09-27 07:45 -0700
Message-ID<8857a25a-e1ec-4571-978c-d8abeac2a2b9@googlegroups.com>
In reply to#28742
> As an alternative approach you could try to have the server-side code generate 
> the SVG snippets and load them with XMLHttpRequest and insert them into 
> the DOM tree. Loading XML (and SVG is XML) is what XMLHttpRequest was 
> originally designed for.

Thank you.  I had considered that, but I also have a need to delete and update the objects.  For both, I need to "get element by ID".  Can that be done with XML?

Jay

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web