jquery 追加和运行标签 <script> VS js 香草



我正在更新我的应用程序,我决定使用不再具有jquery依赖关系的bootstrap 5,并从我的应用中消除这种依赖关系。

因此,我正在将javscript部分从jquery重写为jsvanilla。

我经常使用AJAX来加载不同div中的内容,并根据用户触发的某些事件对其进行后续操作。不幸的是,在某些情况下,我发现自己被迫将脚本标记与html部分挂在一起,以运行无法以任何其他方式执行的javascript函数。

例如:

<script>myFuncrion(val1, val2, val3);</script>
<div id="myDiv">
<div>Other html code ..</div>
</div>

使用jquery,类似这样的东西就足以将标记附加到给定的div并执行javascipt函数

$('#elementToAppend').append(html);

将其转换为香草js我得到了类似的东西

document.getElementById('elementToAppend').innerHTML = html;

所有内容都被正确地附加,但很明显js并没有被执行

我不知道jquery在幕后,但我认为它正在以某种方式被操纵,以便运行javascript部分。

然后我创建了一个函数,可以让恢复正常工作

const functionOne = (elem) => {
// I make the AJAX call...
let jsAndData = getJsAndData(data);

// Append the html string
document.querySelector(elem).innerHTML = jsAndData.cleanData;
// I run the js
eval(jsAndData.js);
}
const getJsAndData = data => {
var js = "";
// Check if there is a <script> tag
let script = data.match(/<script>(.*?)</script>/g);
// If there is a script tag I extrapolate the js content
if (script) {
script.map(val => {
js = val.replace(/</?script>/g, "");
});
// I remove the <script> tag and its content from the html string
let cleanData = data.replace(/<script[^>]*>.*</script>/gm, "");
return { cleanData: cleanData, js: js };
} else {
return { cleanData: data, js: js };
}
};

通过这种方式,我得到了与jquery相同的结果,甚至更好,因为在DOM上不再有任何脚本标记的踪迹

现在,我的问题是:

  1. 我做的事情对吗
  2. 有更好的方法吗
  3. 我是不是完全躲开了

您的方式是正确的。出于安全原因(XSS(,使用innerHTML时不运行脚本标记。

https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML#security_considerations

替代方案:在MDN中,你可以找到这样的破解代码,在不接触前端的情况下从后端处理。我不建议这样做。

const name = "<img src='x' onerror='alert(1)'>";
el.innerHTML = name; // shows the alert

最新更新