代码注入,主要是用来动态加载代码或执行代码。比如处理从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>