Estoy actualizando mi aplicación y he decidido usar bootstrap 5 que ya no tiene la dependencia de jquery y eliminar esta dependencia de mi aplicación también.
Así que estoy reescribiendo la parte de javscript de jquery a js vanilla.
Utilizo mucho AJAX para cargar contenido en diferentes divs y para su posterior manipulación en base a ciertos eventos desencadenados por el usuario. Desafortunadamente, en algunos casos me veo obligado a colgar una etiqueta de script junto con la parte html para ejecutar una función javascript que no puedo ejecutar de otra manera.
Por ejemplo:
<script>myFuncrion(val1, val2, val3);</script> <div id="myDiv"> <div>Other html code ..</div> </div>Con jquery, algo como esto fue suficiente para agregar el marcado a un div dado y ejecutar la función javascipt
$('#elementToAppend').append(html);Convirtiendo esto a vanilla js obtengo algo como esto
document.getElementById('elementToAppend').innerHTML = html;Todo está correctamente anexado, pero obviamente no se ejecuta el js
No sé jquery detrás de escena, pero supongo que está siendo manipulado de alguna manera para que se ejecute la parte de javascript.
Luego creé una función que haría que todo volviera a funcionar
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 }; } };De esta manera obtengo el mismo resultado que tenía con jquery, incluso mejor, porque en el DOM ya no hay rastro de la etiqueta del script.
Ahora, mis preguntas son:
Tu camino es un camino correcto. Por razones de seguridad (XSS), la etiqueta del script no se ejecuta cuando se usa innerHTML.
https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML#security_considerations
Alternativa: en MDN puedes encontrar código hacky como este para trabajar desde el backend sin tocar el frontend. Yo no recomendaría de esta manera.
const name = "<img src='x' onerror='alert(1)'>"; el.innerHTML = name; // shows the alert