假设我收到了对JavaScript和HTML混合的AJAX数据加载请求的响应,例如:
<script>window.alert('Hello World!');</script>
<p>This is a paragraph. Lorem ipsum dolor sit amet...</p>
如果我只是将该响应放入div
或其他容器中,则脚本不会自动执行。我知道这可以通过eval()
函数完成(如下例所示),但是eval
是邪恶的,所以我该如何正确地做到这一点? 注意:我没有使用jQuery。
以下是AJAX加载程序的示例:
function Load(id,url){
var ajax=new XMLHttpRequest();
ajax.onreadystatechange=function(){
if(ajax.readyState!=4)return;
var obj=document.getElementById(id);
if(!obj)return;
obj.innerHTML=ajax.responseText;
// load any scripts
var s=obj.getElementsByTagName('script');
for(var i=0;i<s.length;++i)window.eval(s[i].innerHTML); // <-- bad
}
ajax.open("GET",url,true);
ajax.send(null);
}
答案 0 :(得分:3)
请注意,您正在接收用户的输入并在您网站上的脚本环境中运行。因此,脚本可以执行浏览器/域上运行的JavaScript能够执行的任何操作(包括cookie窃取,XSS,偷渡式恶意软件等)。
您唯一可以现实地做的是减轻风险,而不是eval()用户提供的内容。我建议考虑以下替代方案:
答案 1 :(得分:2)
var newScriptTag = document.createElement('script');
newScriptTag.appendChild(document.createTextNode(
origScriptTag.innerHTML)
document.body.appendChild(newScriptTag);
答案 2 :(得分:0)
我今天通过将JavaScript放在响应HTML的底部来解决这个问题。
我有一个AJAX请求返回了一堆显示在叠加层中的HTML。我需要将单击事件附加到返回的响应HTML / overlay中的按钮。在普通页面上,我将JavaScript包装在“window.onload”或“$(document).ready”中,以便在渲染新叠加层的DOM之后将事件处理程序附加到DOM对象,但是因为这是一个AJAX响应,而不是一个新的页面加载,该事件从未发生过,浏览器从未执行过我的JavaScript,我的事件处理程序从未附加到DOM元素,而我的新功能不起作用。再一次,我通过不在文档的头部使用“$(document).ready”来解决我的“在AJAX响应问题中执行JavaScript”,而是将我的JavaScript放在文档的末尾并让它在HTML之后运行/ DOM已经渲染。