113

I'm currently working on a form which includes some file inputs to upload pictures. There is an onchange() event for those inputs that submits the pictures to an iframe, then dynamically loads the uploaded pictures into the form, with fields to be modified for them (like name and geo-localization).

Since I can't nest forms, the file_input is also contained in an iframe. In the end I use an iframe inside of another iframe. So I have something like this:

<form>
<!-- LOTS OF FIELDS!! -->
<iframe src="file_input_url">
<!-- iframe which loads a page of a form with a file input-->
</iframe>
</form>

and the HTML loaded into the iframe is something like (excluding the html, head and body tags)

<form target="upload_iframe">
<input type="file" onchange="this.form.submit()">
</form>
<iframe name="upload_iframe"></iframe>

This works great, except for the fact that it takes a couple seconds to load the first iframe, so the file input does not load with the rest of the page. This is not visually ideal. I could solve it if I could specify the iframe content without needing to load another page (specified by file_input_url in the first iframe).

Is there a way to specify the iframe content in the same document, or can it only be specified with the src attribute, requiring the load of another page?

Michael
  • 8,362
  • 6
  • 61
  • 88
orlox
  • 1,260
  • 2
  • 9
  • 8
  • It shouldn't take "a couple of seconds" to load that iframe. I'd expect it to be more like a tenth of a millisecond plus the "time to bite bite" (which also should be milliseconds). You should investigate what's causing all the lag - probably something wrong with your server. – Abhi Beckert Aug 04 '20 at 00:33
  • there is also one strange way `````` and in js: ```function _renderMe() {return String(Math.random()}``` – zb' Apr 02 '21 at 11:34

4 Answers4

121

You can .write() the content into the iframe document. Example:

<iframe id="FileFrame" src="about:blank"></iframe>

<script type="text/javascript">
   var doc = document.getElementById('FileFrame').contentWindow.document;
   doc.open();
   doc.write('<html><head><title></title></head><body>Hello world.</body></html>');
   doc.close();
</script>
Alexander
  • 7
  • 1
  • 3
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • 2
    Had thought about this possibility, however, the html that has to be loaded into the iframe is complex, and handling it entirely in javascript in order to write it to the iframe would obscure the implementation too much (up to the point that I prefer to leave it as it is). – orlox Nov 16 '10 at 22:16
  • 3
    @orlox: Get your content from the server using Ajax and inject it. If you don't want to go that way, make a hidden `div` element with your content and place its content in the `iframe` between `` and ``. – stackular Sep 20 '13 at 11:01
  • 14
    The more I learn about iframes restrictions the more I hate them – John Magnolia Jan 21 '14 at 20:40
  • @stackular I he can use ajax he can also simple `src` in iframe. – Handsome Nerd Mar 04 '16 at 16:18
  • This solution is great. I haven't tested in all browsers yet but this allowed me to write full HTML documents with css attributes in the body tag and honor the attributes. Unlike all the other solutions, this seems to write HTML code to the frame that includes head, body tags without manipulating it to some degree. It also didn't affect various encodings I was dealing with where JS solutions that call `escape()` turned UTF-8 into `%u####` that didn't display properly in the frame. – drew010 Jun 27 '16 at 05:43
  • 2
    How do I escape single quotes using this method? Some of them are HTML-important (e.g. class='example'), some are CSS-important (e.g. font-family: 'Verdana';) and some are content (e.g. George O'Malley). – Dan Bechard Dec 01 '16 at 17:11
  • 3
    @Dan: To escape any value to be used in an apostrophe delimited JavaScript string, you first escape backslashes, then apostrophes. For example using C# to output a string in the code: `doc.write('<%= html.Replace("\\", "\\\\").Replace("'", "\\'") %>');`. – Guffa Dec 19 '16 at 16:04
  • @Guffa I figured half of that out on my own (through trial-and-error), but not the other. Thanks for the tip! – Dan Bechard Dec 19 '16 at 21:32
  • Thanks, works great. I also had issues escaping the tag and wrapped the whole thing in commented out HTML comments. As per this thread https://stackoverflow.com/questions/28643272/how-to-include-an-escapedscript-script-tag-in-a-javascript-variable /**/ – Anonymous Oct 16 '19 at 16:23
  • @DanBechard you don't need to escape any quotes. Just wrap everything in backticks (ES2105 templates) - read here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals. `doc.write(\`
    George O'Malley
    \``)
    – danbars Mar 03 '20 at 13:03
57

iframe now supports srcdoc which can be used to specify the HTML content of the page to show in the inline frame.

Ayush Gupta
  • 5,568
  • 2
  • 21
  • 17
35

You can use data: URL in the src:

var html = 'Hello from <img src="http://stackoverflow.com/favicon.ico" alt="SO">';
var iframe = document.querySelector('iframe');
iframe.src = 'data:text/html,' + encodeURIComponent(html);
<iframe></iframe>

Difference between srcdoc=“…” and src=“data:text/html,…” in an iframe.

Convert HTML to data:text/html link using JavaScript.

user
  • 23,260
  • 9
  • 113
  • 101
  • 2
    You don't even need any JavaScript: the `src` attribute can be specified inline if escaped e.g. using `rawurlencode` in PHP: `` – Jake Nov 03 '17 at 16:26
  • 1
    Microsoft added support for this at pretty much the same time as they added support for `srcdoc`, and `srcdoc` is the better way to do this. Data URLs are only widely supported for images and CSS - as far as I know no version of Internet Explorer supports them in an iframe. – Abhi Beckert Aug 04 '20 at 00:07
  • Isn't there some length restriction with the `src` attribute? – Crashalot Aug 05 '21 at 00:25
6

In combination with what Guffa described, you could use the technique described in Explanation of <script type = "text/template"> ... </script> to store the HTML document in a special script element (see the link for an explanation on how this works). That's a lot easier than storing the HTML document in a string.

Community
  • 1
  • 1
ximo
  • 192
  • 1
  • 8
  • On second thought, that wouldn't work very well for a full HTML document. Tags such as ``, ``, ` – ximo Sep 16 '11 at 16:04
  • That does not appear to be an issue, the HTML tags inside scripts are ignored. – HBP Sep 19 '13 at 12:56
  • You're right :) I hadn't actually tried the technique yet when I wrote that, and must have picked up that assumption from somewhere. I later found out that anything within a ` – ximo Sep 22 '13 at 11:56
  • You can include the content within the iframe itself, e.g. `` – prototype Sep 04 '21 at 02:16