第一关:如果你能避免使用eval
,避免使用eval
。您的代码是否有从POST
回来?因为如果你愿意使用GET
相反,你可以在脚本元素只是追加到页面:
var script = document.createElement('script');
script.src = "http://example.com" +
"?" + encodeURIComponent("param1name") + "=" + encodeURIComponent("param1value") +
"&" + encodeURIComponent("param1name") + "=" + encodeURIComponent("param2value");
var parent = document.body
|| document.documentElement
|| document.getElementsByTagName('head')[0];
parent.appendChild(script);
完成。
或者如果它必须是POST
,是否真的必须是实际的脚本代码?难道这是根据页面上的代码解释了的数据吗?如果你可以这样做,JSON是一种有用的数据格式。
但如果有为POST
,并返回给你有是相对于实际数据脚本代码,那么我们将不得不做一些像eval
。 :-)
eval
本身非常非常特别。它在它所使用的范围内工作,即使它看起来有点像一个函数,并不是函数的工作方式。所以在全球范围内实际评估脚本代码是很困难的,除非eval
调用实际上是在全局范围(不在任何函数调用中),当然你不能在这里做到这一点 —你必须从你的ajax回调中触发这个,所以根据定义,这发生在一个函数内。 (编辑:我只是想到了一个办法,在全球范围内实际使用eval
,在一个函数中看到更新的答案的结束,但它的邪恶和恐怖的和错误的。)
原因你可能看到建议说使用window.eval
是许多现代浏览器提供window.eval
(而不是eval
),它在全局范围内评估给定的代码。但它并不适用于所有的浏览器,当然不是老的。
虽然有解决方法。 IE家族提供的execScript
是非常类似类似于其他浏览器提供的window.eval
,在最坏的情况下,您可以使用script
元素。下面是工作在几乎所有全球eval函数:
window.evalInGlobalScope = (function() {
var fname, scr;
// Get a unique function name
do {
fname = "__eval_in_global_test_" + Math.floor(Math.random() * 100000);
}
while (typeof window[fname] !== 'undefined');
// Create test script
scr = "function " + fname + "() { }";
// Return the first function that works:
return test(evalInGlobalScope_execScript) ||
test(evalInGlobalScope_windowEval) ||
test(evalInGlobalScope_theHardWay) ||
evalInGlobalScope_fail;
function test(f) {
try {
f(scr);
if (typeof window[fname] === 'function') {
return f;
}
}
catch (e) {
return false;
}
finally {
try { delete window[fname]; } catch (e) { window[fname] = undefined; }
}
}
function evalInGlobalScope_execScript(str) {
window.execScript(str);
}
function evalInGlobalScope_windowEval(str) {
window.eval(str);
}
function evalInGlobalScope_theHardWay(str) {
var parent, script, d = document;
parent = d.body || d.documentElement || d.getElementsByTagName('head')[0];
if (parent) {
script = d.createElement('script');
script.appendChild(d.createTextNode(str));
parent.appendChild(script);
}
}
function evalInGlobalScope_fail() {
throw "evalInGlobalScope: Unable to determine how to do global eval in this environment";
}
})();
..和here's a live example of using it。
请注意,所有代码只能运行一次的代码;被选中的功能被分配到window
上的evalInGlobalScope
属性。
另请注意,我没有给它任何返回值。那是因为“硬路”版本基本上不能返回任何返回值,所以最安全的是它们都没有。请注意,我不确定哪些浏览器仍然需要“困难的方式” —现在几乎所有东西都有execScript
和/或window.eval
。
更新:我上面说你不能在全局范围内使用eval
在一个函数中。从技术上讲,这是真的,但我想到一种方法来解决这个问题。这是邪恶和恐怖的和错误的,但它的工作:使用setTimeout
代替,并给它的0
超时:
setTimeout("your code here", 0);
当你给setTimeout
一个字符串,它在超时后执行就可以了 —的eval
,全球范围内的。
再一次,它是邪恶的,可怕的和错误的,它有一个额外的缺点,即它是异步的(而我们的evalInGlobalScope
函数,eval同步发生),但它确实......排序......工作。 (Live copy)我不要推荐它。
实际上,您可以在jsFiddle中成功完成AJAX调用,请参阅此[参考页](http://doc.jsfiddle.net/use/echo.html)。 –
单词'I'大写英文。 –