用于运行远程代码的eval的替代方案

时间:2011-01-05 14:21:03

标签: javascript jquery eval

是否可以使用eval立即运行远程& amp;可信赖的JavaScript代码。

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

我知道javascript的同步加载是建议的。但是如果没有选择,那么使用上面的eval有任何跨浏览器替代方案。

[编辑]

为了更详细地阐明,正在加载的代码是一个自执行功能。哪个需要在doSomethingWidthCode之前执行。它也是从同一域上的服务器加载,因此它是受信任的。

4 个答案:

答案 0 :(得分:3)

动态脚本文本插入是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);

唯一需要提及的是:textContent在InternetExplorers中不可用。您需要在那里使用.text,因此稍加检测可以使其跨浏览器兼容。

修改

要获得syncronous加载动态脚本代码,您可以添加nscr.async = true;。无论如何,这只适用于尖端浏览器。

答案 1 :(得分:1)

在这种情况下我会使用JSONP。雷蒙德·卡姆登为这个概念提供了excellent introduction

http://playground.itcouldbe9.com/syncjsonp/提供了在这种情况下使用JSONP的快速示例。

答案 2 :(得分:0)

您可以将代码返回包装在函数内,并在请求完成时执行该函数。例如,这是您的远程代码:

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

然后当您的请求完成后,您可以将该代码注入javascript标记,然后调用函数hi()

答案 3 :(得分:0)

为什么不使用回调?

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

编辑:

好的,然后试试这个:

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

我认为剩下的唯一选择就是投票:

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