alternatives to eval for running remote code

2019-05-11 05:24发布

问题:

Are there any alternatives to using eval to immediatly run remote & trusted javascript code.

function load(filePath) {
    var o = $.ajax({
        url: filePath,
        dataType: 'html',
        async: false 
    }); 

    eval(o.responseText);
}

load("somePath");
// run a function that relies on the code from o.responseText being loaded
doSomethingWithCode();

I'm aware that synchronous loading of javascript is adviced againts. But if there is no choice are there any cross browser alternatives for the use of eval above.

[Edit]

To clarify in more detail the code being loaded is a self executing function. Which needs to execute before doSomethingWidthCode. It's also being loaded from the server on the same domain hence its trusted.

回答1:

Dynamic script text insertion is the only alternative to eval.

var head    = document.getElementsByTagName('head')[0] || document.documentElement,
    nscr    = document.createElement('script');

    nscr.type           = 'text/javascript';
    nscr.textContent    = o.responseText;
    nscr.setAttribute('name', 'dynamically inserted');
    nscr.onload         = nscr.onreadystatechange = function() {
              if( nscr.readyState ) {
                   if( nscr.readyState === 'complete' || scr.readyState === 'loaded' ) {
                      nscr.onreadystatechange = null;
                       doSomethingWithCode();
              }
              else {
                  doSomethingWithCode();
              }
    };

    head.insertBefore(nscr, head.firstChild);

Only thing to mention: textContent is not available in InternetExplorers. You would need to use .text instead there, so a little detection for that makes it cross-browser compatible.

edit

To have a syncronous loading dynamic script tag, you could add nscr.async = true;. Anyway, this only works in cutting edge browsers.



回答2:

I would use JSONP in this case. Raymond Camden provides and excellent introduction to the concept.

A quick example of using JSONP in this situation is available at http://playground.itcouldbe9.com/syncjsonp/.



回答3:

You can have your code returned wrapped inside a function, and when the request completes, execute that function. For example, this is your remote code:

function hi(){alert('hi');}

And then when your request is complete, you can inject that code into a javascript tag and then call the function hi()



回答4:

why not use a callback?

eval('(function(){' + o.responseText + ';})(); doSomethingWithCode();')

EDIT:

OK then try this:

var o = $.ajax({
    url: filePath,
    dataType: 'html',
    async: false
    success: function(responseText){
        eval('(function(){' + responseText + '})()');
        doSomethingWithCode();
    });
}); 

I think the only option left would be polling:

(function(){
    if (o.responeText)
        doSomethingWithCode();
    else 
        setTimeout(arguments.callee, 13);
})();