[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.javascript

alternatives to eval() for this case

Jay Braun

9/25/2015 5:27:00 PM

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
8 Answers

ram

9/25/2015 6:37:00 PM

0

Jay Braun <lyngwyst@gmail.com> writes:
>I have read much of the on-line material about the drawbacks of eval().

For some applications »eval« is great. But when input
comes from »external« sources or when the program
controls critical systems, it is dangerous.

>eval(xmlhttp.responseText);

I /do/ deem a server to be an external source! When the
answer is JSON, XML or some other format, there are usually
parsers or interpreters for JSON, XML, or some other format.
Such parsers usually are a safer choice.

>eval() is not only slow (as expected), but does not complete
>the parsing of the file.

Maybe the JavaScript implementation has some variable like
(I am making this name up)

EVALSIZELIMIT

which one can tweak? But a specific parser might be the better
choice.

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

But it should be in /some/ notation, and one can buy or
write a parser for /that/ notation.

Danny

9/25/2015 10:40:00 PM

0

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

}

Jay Braun

9/25/2015 10:51:00 PM

0

> 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

JR

9/26/2015 3:35:00 AM

0

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-misunder...


> 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...


--
Joao Rodrigues

Thomas 'PointedEars' Lahn

9/26/2015 7:33:00 AM

0

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...

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#Attr... 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://requirej...

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

Jay Braun

9/27/2015 3:14:00 AM

0

> 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

Martin Honnen

9/27/2015 8:30:00 AM

0

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.

Jay Braun

9/27/2015 2:46:00 PM

0

> 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