66

I have a string which looks like:

<html><head><title>example</title></head><body>some example text</body></html>

I get this string returned as a result to an AJAX request.

I would like the browser to render and display that string. The idea would be to do something like:

$('html').parent().html(myString);

Well, that doesn't work. I've attempted to use an IFRAME but I haven't figured out how to get that to work either.

Note: It is impossible for me to change this string. It is also impossible for me to regenerate this string in a subsequent call to the server (otherwise I could just redirect the browser to that url).

Ken Browning
  • 28,693
  • 6
  • 56
  • 68
  • As far as I'm aware there's no parent for the `html` element, IE6 and IE7 excepted. (But they hardly count) So you need to look at operations which work directly on `$('html')` -- outerhtml sounds about right. – wombleton Aug 06 '09 at 02:24

5 Answers5

141

The document.open/write/close methods will do what you want:

var newDoc = document.open("text/html", "replace");
newDoc.write(myString);
newDoc.close();

Unless you pass in the replace parameter, the document.open call adds page history. So users would have to click back twice to go to the previous page.

Jon Benedicto
  • 10,492
  • 3
  • 28
  • 30
  • 1
    Thanks, this works perfectly. Do you happen to know if this behaves differently in any non-ie browsers? – Ken Browning Aug 06 '09 at 02:52
  • 1
    Since these have been part of the DOM for a very long time, I'd expect them to work correctly across all modern browsers. – Jon Benedicto Aug 06 '09 at 03:16
  • 1
    Hey, currently there is a problem with firefox and hard refresh when using solution. Is there a workaround nowadays? –  May 09 '13 at 10:50
  • Can you open a new window and show the content there? – Johncl Jun 15 '15 at 08:50
  • This solution works for me in W7/MF, but when executing statement newDoc.write(myString) I receive Permission denied error in W7/IE with error number number -2146828218. – Rudolf Dvoracek Mar 02 '16 at 23:10
  • this does not cancel any timeouts you've set, so if you try to reload a page inside setInterval, you'll also have to cancel the timer – Matiaan Oct 01 '19 at 06:42
  • The two argument `document.open` is now obsolete because it's the default behavior: https://developer.mozilla.org/en-US/docs/Web/API/Document/open#Two-argument_document.open – increscent Dec 31 '19 at 02:48
16

You could just strip out the html tags, and then put everything inside the html element:

$('html').html(myString.replace(/<html>(.*)<\/html>/, "$1"));
Marius
  • 57,995
  • 32
  • 132
  • 151
  • 1
    Thanks but this doesn't work. No matter what value I try, the result of `$('html').html(somevalue)` is a blank page with an empty DOM (in IE). – Ken Browning Aug 06 '09 at 02:50
  • 6
    No need for stripping `$("html").html(myString)` does it automatically. – inf3rno Jun 19 '15 at 10:09
7

At least in firefox(47.0) the solution:

var newDoc = document.open("text/html", "replace");
newDoc.write(response);
newDoc.close(); 

does not work as suggested since pressing the back button on firefox still loads the previous history entry - i.e. the entire point of using "replace" is to avoid having users click their back button only to be greeted by the view of the page before the last time the document.write() was called. The way of doing this that does not cause the aforementioned effect is simply calling methods on the document object directly:

document.open("text/html", "replace");
document.write(response);
document.close();

Using the replace option not only avoids filling the users history with garbage, but also helps in dealing with the issues that arise from the weird ways in which browsers often handle the history entries created by javascript, as sometimes allowing the browser to log the changes made to the document by javascript in history might have unexpected results when handling the back/forward operations (for instance adding 'wyciwyg://(somenumber)' to the url after performing a document.write() on the document that had its history reverted to a previous state).

grssn
  • 526
  • 6
  • 8
3

Another variation to try might be

$('html').replaceWith(myString);

http://api.jquery.com/replaceWith/

emtrane
  • 1,049
  • 1
  • 8
  • 10
  • Note that this replaces the jQuery object as well, so if you're keeping references you need to update them. – Aram Kocharyan Mar 18 '12 at 12:07
  • 5
    Does not work. `HierarchyRequestError: Node cannot be inserted at the specified point in the hierarchy` in firefox. – inf3rno Jun 19 '15 at 09:54
  • Almost the same result as inf3rno => Node cannot replace itself – Mauro Feb 03 '16 at 17:29
  • 1
    Using chrome I got this error:Uncaught DOMException: Failed to execute 'replaceChild' on 'Node': Nodes of type '#document-fragment' may not be inserted inside nodes of type '#document'. – Rafael Xavier Mar 09 '19 at 13:26
1
document.documentElement.innerHTML = myString;

It works except for IE9.

Serg
  • 6,742
  • 4
  • 36
  • 54