0

I want to load an iframe that does nothing else than load a JavaScript file from a given URL. While this would be easy by loading a simple HTML page into the iframe that only contains the <script> tag to load the JavaScript file, but that would require two requests to the server.

So my idea is to write the code to load the JS file from the calling method in the parent window into the empty iframe.

Something like this works on all browsers:

function createScriptFrame(container, url) {
    const frame = document.createElement('iframe');
    container.appendChild(frame);
    const doc = frame.contentDocument;
    doc.open();
    doc.write('<html><body><script src="' + url + '"></script></body></html>');
    doc.close();
}

But using document.write is a really nasty way of doing it. Chrome even complains with a warning in the console: [Violation] Avoid using document.write().

I've come up with a few alternative approaches, for example:

// same as above until doc.open()
const s = doc.createElement('script');
s.src = url;
doc.head.appendChild(s);

or

const s = doc.createElement('script');
s.appendChild(doc.createTextNode('(function() { const s = 
document.createElement("script"); s.src = "' + url + '"; 
document.body.appendChild(s); })()'));
doc.head.appendChild(s);

These work nicely in Chrome and Safari but not in Firefox.

I've compiled a test with several methods to load the script: https://embed.plnkr.co/l8DwUBQs7cQsi938eTOn/

Any ideas how to make this work?

2 Answers 2

2

You can create a blob and open it

var url = 'foo'
var blob = new Blob([
  '<html><body><script src="' + url + '"></script></body></html>'
], {type: 'text/html'})
var iframeUrl = URL.createObjectURL(blob)
console.log(iframeUrl)

...Or if you like a base64 url

You can also use the srcdoc but it isn't supported by IE/Edge

Sign up to request clarification or add additional context in comments.

6 Comments

Nice idea, I've added both blob and data URL to the Plunk, but neither works in any browser. The frame content is properly created but the frame.js is never loaded. Could be a security constraint.
you must add the base tag or use absolute path to your javascript file
there is one different between blob and dataURI in that blobs will inherit the Origin property which can be important for accessing the same local storage, cookies, indexeddb, cors-request etc
Using the absolute URL worked for both data URL and blob. Thanks! Still need to find out about browser support...
caniuse.com/#feat=bloburls with android you might have to use webkit prefix
|
0

Instead of document.write() you could now use a new attribute on iframe which is srcDoc.

https://caniuse.com/iframe-srcdoc

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.