动态沙盒化内联JavaScript的最佳方法是什么?

6
我是一名能够翻译文本的助手。
我有一个WordPress插件,使用AJAX加载页面,以确保与其他插件和“小部件”兼容。
目前,我使用以下代码来评估所有内联JS,该JS位于要更新的内容块中:
  function do_JS(e){
        var Reg = '(?:<script.*?>)((\n|.)*?)(?:</script>)';
        var match    = new RegExp(Reg, 'img');
        var scripts  = e.innerHTML.match(match);
        var doc = document.write;
        document.write = function(p){ e.innerHTML = e.innerHTML.replace(scripts[s],p)};
        if(scripts) {
            for(var s = 0; s < scripts.length; s++) {
                var js = '';
                var match = new RegExp(Reg, 'im');
                js = scripts[s].match(match)[1];
                js = js.replace('<!--','');
                js = js.replace('-->','');
                eval('try{'+js+'}catch(e){}');
            }
        }
        document.write = doc;
    }

我希望能够更好地隔离JS,以减小冲突的风险。我的一个想法是动态创建一个<iframe>并在其中运行JS,但我希望有一种更好的方法既可以确保兼容性,又可以增加安全性。

2个回答

2

不幸的是,这个插件在我完全控制不了的数百个站点上运行,所以我无法像myspace这样的网站一样通过Caja运行JS片段。解决方案需要可再分发。 - Aaron Butacov

1

很可能这不会给你完全需要的东西,但是将你的脚本文本包装在一个函数或自执行函数文字中怎么样呢(function(){/*...*/})()

var strEval =  'try{';
strEval += 'widget[' + intWidgetNumber + '] = (function(){';
strEval += js;
strEval += '})();';
strEval += '}catch(e){}';

这比直接使用eval提供了更多的保护,并将代码保留在同一文档中。缺点是,如果您导入的代码对全局变量很混乱(这可能就是您问这个问题的原因),它们仍然可能会破坏其他代码。如果他们使用this关键字,他们的代码可能无法按预期工作。但至少这将在封装的范围内保留正确声明的变量和函数声明。

我经常使用第三方代码(主要是糟糕透顶的广告代码),我发现最好的解决方案是将您的站点代码包装在一个长而独特的命名空间中(mySiteUtils、mySiteGames等,或com.mysite.utils、com.mysite.games等)。如果广告代理商决定放置与您完全相同的命名空间代码,他们将破坏您的页面,但到目前为止,这种情况从未发生过。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接