我正在为一些任意代码创建一个包装器(让我们称之为托管代码)。托管代码可能包含一些在窗口范围内定义的功能,并且是页面上其他脚本所期望的(可怕的,1997,实践,我知道,但这是我必须处理的),作为全局函数。
包装器的目的是延迟执行包装代码,直到加载jQuery。它看起来像这样:
(function () {
var once = true,
check = setInterval(function () {
if (window.$ && once) {
once = false; // setInterval can stack up if the UI freezes. Ensure this only gets called once.
executeBundle();
clearInterval(check);
console.log('Jquery loaded');
}
}, 100);
})()
// Wrapper proper
function executeBundle() {
// oodles of code of any origin
}
既然托管代码已经包含在executeBundle
函数中,那么在其中声明的所有函数/变量都将作用于该函数。对于托管代码本身而言,这不是一个问题,但对于可能依赖于它提供的全局函数的其他单独加载的脚本。
我想知道是否有人知道像eval
这样的策略,但没有安全问题,这可能会让我保留运行托管代码的窗口范围。限制是我根本无法修改托管代码 - 只是包装器。
答案 0 :(得分:2)
基于T.J. Crowder的惊人答案,我意识到我可以将托管代码添加到<script>
元素并将其添加到<head>
,如下所示:
var codeBundle = // Code in one long string
function evaluateBundle() {
var script = $('<script type="text/javascript"/>')
script.html(codeBundle);
$('head').append(script);
}
让解析器评估代码。
答案 1 :(得分:1)
我想知道是否有人知道像
eval
这样的策略,但没有安全问题
如果你自己编写eval
自己的代码,那么无论如何都要将它放在script
代码中,那么就没有任何安全问题。您以任何一种方式运行代码。
如果您正在包装的代码将直接显示在evaluateBundle
中并且它具有应该位于的声明(var
和函数声明),则您无法执行此操作全球范围。处理那些需要修改包装代码。
如果您单独加载该代码,可以执行此操作,然后对其执行全局评估。例如,将它放在一个非JavaScript类型的脚本块中,这样浏览器就不会执行它:
<script type="x-code-to-wrap"></script>
......然后:
function evaluateBundle() {
var code = document.querySelector('script[type="x-code-to-wrap"]').textContent;
(0, eval)(code);
}
((0, eval)(code)
位是全局eval
,more on MDN)。
您可能需要调整textContent
部分,以实现跨浏览器兼容性。 This question's answers建议使用jQuery&#39; html
函数:
function evaluateBundle() {
(0, eval)($('script[type="x-code-to-wrap"]').html());
}