I\'ve got a script that inserts some content into an element using innerHTML
.
The content could for example be:
Made this new helper function in TypeScript, maybe someone will appreciate it. If you remove type declaration from script parameter it will just be plain JS.
const evalPageScripts = () => {
const scripts = document.querySelectorAll('script');
scripts.forEach((script: HTMLScriptElement) => {
const newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = script.src;
if (script.parentNode) {
script.parentNode.removeChild(script);
}
return document.body.appendChild(newScript);
})
};
export default evalPageScripts;
Expending the answer of Lambder
document.body.innerHTML = '<img src="../images/loaded.gif" alt="" > onload="alert(\'test\');this.parentNode.removeChild(this);" />'
;
You can use base64 image to create and load your script
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjHxIGmVAAAADUlEQVQYV2P4//8/AwAI/AL+iF8G4AAAAABJRU5ErkJggg=="
onload="var script = document.createElement('script'); script.src = './yourCustomScript.js'; parentElement.append(script);" />
Or if you have a Iframe
you can use it instead
<iframe src='//your-orginal-page.com' style='width:100%;height:100%'
onload="var script = document.createElement('script'); script.src = './your-coustom-script.js'; parentElement.append(script);"
frameborder='0'></iframe>
Try function eval().
data.newScript = '<script type="text/javascript">//my script...</script>'
var element = document.getElementById('elementToRefresh');
element.innerHTML = data.newScript;
eval(element.firstChild.innerHTML);
This is a real example from a project that i am developing. Thanks to this post
Here's a shorter, more efficient script that also works for scripts with the src
property:
function insertAndExecute(id, text) {
document.getElementById(id).innerHTML = text;
var scripts = Array.prototype.slice.call(document.getElementById(id).getElementsByTagName("script"));
for (var i = 0; i < scripts.length; i++) {
if (scripts[i].src != "") {
var tag = document.createElement("script");
tag.src = scripts[i].src;
document.getElementsByTagName("head")[0].appendChild(tag);
}
else {
eval(scripts[i].innerHTML);
}
}
}
Note: whilst eval
may cause a security vulnerability if not used properly, it is much faster than creating a script tag on the fly.
Try this, it works for me on Chrome, Safari & Firefox:
var script = document.createElement('script');
script.innerHTML = 'console.log("hi")';
document.body.appendChild(script);
--> logs "hi"
One thing to note though, is that the following div-nested script will NOT run:
var script = document.createElement('div');
script.innerHTML = '<script>console.log("hi")</script>';
document.body.appendChild(script);
--> doesn't log anything
For a script to run it has to be created as a node then appended as a child. You can even append a script inside a previously injected div & it will run (I've run into this before when trying to get ad server code to work):
var div = document.createElement('div');
div.id = 'test-id';
document.body.appendChild(div);
var script = document.createElement('script');
script.innerHTML = 'console.log("hi")';
document.getElementById('test-id').appendChild(script);
--> logs "hi"
@phidah... Here is a very interesting solution to your problem: http://24ways.org/2005/have-your-dom-and-script-it-too
So it would look like this instead:
<img src="empty.gif" onload="alert('test');this.parentNode.removeChild(this);" />