代码注入,主要是用来动态加载代码或执行代码。比如处理从server端返回的JSON代码;又比如加载一段JavaScript代码。
下面讨论解决问题的几种可能方案。
下面的例子用来说明 eval和window.eval的区别。
var v=0;
function f_a() { eval("var v=5;"); }
function f_b() { window.eval("var v=5;"); }
f_a(); alert(v); // v = 0
f_b(); alert(v); // v = 5
可以通过在DOM中添加script节点来执行JavaScript代码。
function eval_script_src(url){
var script = document.createElement('script');
script.setAttribute("type", "application/javascript");
script.setAttribute("src", url);
document.head.appendChild(script);
//document.head.removeChild(script);
}
function eval_script_text(code){
var script = document.createElement('script');
script.setAttribute("type", "application/javascript");
script.text = code;
document.head.appendChild(script);
//document.head.removeChild(script);
}
这个放法可以用来加载第三方站点的JavaScript脚本。
下面的代码可以用于测试各种代码注入方法在不同浏览器中的行为。
<textarea id="log" style="width:100%;height:100%;">
</textarea>
<script type="text/javascript">
function log(txt){
document.getElementById('log').value += "\n"+txt;
}
function eval_inside(code){
eval(code);
}
function eval_inside_window(code){
window.eval(code);
}
function eval_inside_call(code){
eval.call(window,code);
}
function eval_inside_execScript(code){
try{
window.execScript(code);
}catch(e){
}
}
function eval_inside_timeout(code){
code = "eval('"+code.replace(/'/g,'"')+"')";
setTimeout(code,0);
}
function eval_script_src(code){
var script = document.createElement('script');
script.setAttribute("type", "application/javascript");
script.setAttribute("src", "data:,"+escape(code));
document.head.appendChild(script);
//document.head.removeChild(script);
}
function eval_script_text(code){
var script = document.createElement('script');
script.setAttribute("type", "application/javascript");
script.text = code;
document.head.appendChild(script);
//document.head.removeChild(script);
}
var code = 'var v_$n=5;t_$n=4;function f_$n(s){log("... f_$n: v_$n="+v_$n+" , t_$n="+t_$n + " " + s);}'
+ 'f_$n("(inside)");'
;
var code2 = 'try{f_$n("(outside)");}catch(e){} try{log(" result: v_$n="+v_$n+" , t_$n="+t_$n);}catch(e){}';
function test_js(n,test_name, func_name){
var txt = code.replace(/\$n/g, n);
log('');
log('*** '+test_name+' ***');
func_name(txt);
}
var n = 0;
n++;
test_js(n, "eval", eval);
eval(code2.replace(/\$n/g, n));
n++;
test_js(n, "eval inside", eval_inside);
eval(code2.replace(/\$n/g, n));
n++;
test_js(n, "window.eval", eval_inside_window);
eval(code2.replace(/\$n/g, n));
n++;
test_js(n, "eval.call", eval_inside_call);
eval(code2.replace(/\$n/g, n));
n++;
test_js(n, "window.execScript", eval_inside_execScript);
eval(code2.replace(/\$n/g, n));
n++;
test_js(n, "script.src", eval_script_src);
eval(code2.replace(/\$n/g, n));
n++;
test_js(n, "script.text", eval_script_text);
eval(code2.replace(/\$n/g, n));
n++;
test_js(n, "setTimeout", eval_inside_timeout);
eval(code2.replace(/\$n/g, n));
</script>