alternatives to eval for running remote code

让人想犯罪 __ 提交于 2019-12-05 23:27:39

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.

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

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

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);
})();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!