86

I'm looking for a tool that will give me the proper generated source including DOM changes made by AJAX requests for input into W3's validator. I've tried the following methods:

  1. Web Developer Toolbar - Generates invalid source according to the doc-type (e.g. it removes the self closing portion of tags). Loses the doctype portion of the page.
  2. Firebug - Fixes potential flaws in the source (e.g. unclosed tags). Also loses doctype portion of tags and injects the console which itself is invalid HTML.
  3. IE Developer Toolbar - Generates invalid source according to the doc-type (e.g. it makes all tags uppercase, against XHTML spec).
  4. Highlight + View Selection Source - Frequently difficult to get the entire page, also excludes doc-type.

Is there any program or add-on out there that will give me the exact current version of the source, without fixing or changing it in some way? So far, Firebug seems the best, but I worry it may fix some of my mistakes.

Solution

It turns out there is no exact solution to what I wanted as Justin explained. The best solution seems to be to validate the source inside of Firebug's console, even though it will contain some errors caused by Firebug. I'd also like to thank Forgotten Semicolon for explaining why "View Generated Source" doesn't match the actual source. If I could mark 2 best answers, I would.

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
Jeremy Kauffman
  • 10,293
  • 5
  • 42
  • 52
  • Hmmm, I thought that he was asking for the reverse-- the exact HTML emitted by the server. Jeremy? – Justin Grant Nov 17 '09 at 18:48
  • never mind, just saw the new comment. Now it makes more sense what you're trying to do-- thanks for clarifying. I'll update my answer accordingly. – Justin Grant Nov 17 '09 at 18:51
  • It's remarkable that many viewers of this post missed the main point, which is that static source can't be used to analyze pages that have been modified by javascript. Firebug is great for this, but it would be nice if there were and IE tool to do the same, since browser compatibility is a big issue with IE. – Paul Keister Nov 21 '09 at 19:55
  • This is a duplicate: http://stackoverflow.com/questions/1204482/how-to-view-the-source-of-currently-displayed-html-pagedynamically-than-the-ori. While that question is older, I prefer this one – Casebash May 05 '10 at 12:17
  • @Paul, how is that remarkable? – Pops May 05 '10 at 14:34
  • Because DOM changes are mentioned in the very first sentence, the post seems pretty clear. However, I didn't see the original version before any edits. – Paul Keister May 06 '10 at 05:53
  • 1
    Firebug does not fix any errors in HTML. It just renders tags out of the Firefox DOM. Firebug 1.6 avoids adding elements; for all versions of Firebug you can avoid changing the DOM by disabling the Console panel. – johnjbarton Aug 02 '10 at 04:32
  • Can this be done for other pages by using javascript? Is there a way to get the fully generated html content of a web page of a given url, by using javascript? – phabtar Jul 17 '13 at 10:08
  • 1
    I've just learned so much from this question! – Sergey Orshanskiy Oct 14 '13 at 01:38
  • Check out the awesome bookmarklet posted below by Johnny5. Works in Firefox anyway (with one click), though Firefox already has a developer tool for this (multiple clicks: Ctrl+A, right-click, E). – Jon Coombs Jan 03 '15 at 22:09
  • I have felt the need for this in the past, but is it necessary if the code is written following best practices such that it can be linted and unit tested? – None Nov 29 '16 at 23:50

17 Answers17

34

Justin is dead on. The key point here is that HTML is just a language for describing a document. Once the browser reads it, it's gone. Open tags, close tags, and formatting are all taken care of by the parser and then go away. Any tool that shows you HTML is generating it based on the contents of the document, so it will always be valid.

I had to explain this to another web developer once, and it took a little while for him to accept it.

You can try it for yourself in any JavaScript console:

el = document.createElement('div');
el.innerHTML = "<p>Some text<P>More text";
el.innerHTML; // <p>Some text</p><p>More text</p>

The un-closed tags and uppercase tag names are gone, because that HTML was parsed and discarded after the second line.

The right way to modify the document from JavaScript is with document methods (createElement, appendChild, setAttribute, etc.) and you'll observe that there's no reference to tags or HTML syntax in any of those functions. If you're using document.write, innerHTML, or other HTML-speaking calls to modify your pages, the only way to validate it is to catch what you're putting into them and validate that HTML separately.

That said, the simplest way to get at the HTML representation of the document is this:

document.documentElement.innerHTML
s4y
  • 50,525
  • 12
  • 70
  • 98
  • 1
    So, to rephrase this answer, this is like compiling a program, optimizing or otherwise modifying the code with some tool or even infecting the program with a virus, and then asking for the source code of the result. The transformation HTML->DOM is a one-way function. – Sergey Orshanskiy Oct 14 '13 at 01:36
  • +1, holy hell, that works to see the code before and after each modification. very smart thinking! Thank you – jimjim Jul 02 '15 at 05:18
  • This may be true, but doesn't quite answer the question. It is perfectly possible to convert the current manipulated DOM back into HTML, allowing you to "view the generated source". This is occasionally quite useful, for example if you need to check a single piece of JavaScript against a realistic test harness. – superluminary Jan 11 '16 at 13:43
32

[updating in response to more details in the edited question]

The problem you're running into is that, once a page is modified by ajax requests, the current HTML exists only inside the browser's DOM-- there's no longer any independent source HTML that you can validate other than what you can pull out of the DOM.

As you've observed, IE's DOM stores tags in upper case, fixes up unclosed tags, and makes lots of other alterations to the HTML it got originally. This is because browsers are generally very good at taking HTML with problems (e.g. unclosed tags) and fixing up those problems to display something useful to the user. Once the HTML has been canonicalized by IE, the original source HTML is essentially lost from the DOM's perspective, as far as I know.

Firefox most likley makes fewer of these changes, so Firebug is probably your better bet.

A final (and more labor-intensive) option may work for pages with simple ajax alterations, e.g. fetching some HTML from the server and importing this into the page inside a particular element. In that case, you can use fiddler or similar tool to manually stitch together the original HTML with the Ajax HTML. This is probably more trouble than it's worth, and is error prone, but it's one more possibility.

[Original response here to the original question]

Fiddler (http://www.fiddlertool.com/) is a free, browser-independent tool which works very well to fetch the exact HTML received by a browser. It shows you exact bytes on the wire as well as decoded/unzipped/etc content which you can feed into any HTML analysis tool. It also shows headers, timings, HTTP status, and lots of other good stuff.

You can also use fiddler to copy and rebuild requests if you want to test how a server responds to slightly different headers.

Fiddler works as a proxy server, sitting in between your browser and the website, and logs traffic going both ways.

Justin Grant
  • 44,807
  • 15
  • 124
  • 208
  • Familiar with Fiddler, it's not an easy way of doing what I want (viewing the generated source of a page after it's been changed by the user). – Jeremy Kauffman Nov 17 '09 at 18:50
  • 1
    he wants the source of the page after javascript has modified the dom. – Byron Whitlock Nov 17 '09 at 19:04
  • I'm not the downvoter, but your answer has nothing to do with the question itself. The question may have been edited since you commented. – bradlis7 Nov 17 '09 at 19:06
  • yep, I know that now... the original question didn't mention that important detail, though. :-) Once I got the new info from the OP, I just updated my answer. But I think my original answer was a reasonable answer to the original question. Even though it's not the best answer (I like Forgotten Semicolon's much better!), I'm wondering what made my answer worthy of a downvote. Not a big deal, just wondering. – Justin Grant Nov 17 '09 at 19:08
  • Thanks for this explanation regarding the current HTML existing only inside of the browser's DOM. This is the crux of my problem and I didn't understand that when I asked. It makes me believe that what I'm asking for is essentially impossible. – Jeremy Kauffman Nov 17 '09 at 19:14
  • Cool, glad to help. Yep, I think what you're trying to do is impossible. Check out the links on Forgotten Semicolon's answer-- they explain the situation well. – Justin Grant Nov 17 '09 at 19:45
21

I know this is an old post, but I just found this piece of gold. This is old (2006), but still works with IE9. I personnally added a bookmark with this.

Just copy paste this in your browser's address bar:

javascript:void(window.open("javascript:document.open(\"text/plain\");document.write(opener.document.body.parentNode.outerHTML)"))

As for firefox, web developper tool bar does the job. I usually use this, but sometimes, some dirty 3rd party asp.net controls generates differents markups based on the user agent...

EDIT

As Bryan pointed in the comment, some browser remove the javascript: part when copy/pasting in url bar. I just tested and that's the case with IE10.

Johnny5
  • 6,664
  • 3
  • 45
  • 78
  • Wow, this is PURE GOLD indeed! Works great with a single click on the bookmark. At least, it did in Firefox just now. With Chrome, the popup got rendered--maybe it ignores the "text/plain"? – Jon Coombs Jan 03 '15 at 22:06
  • I copy paste this in my browser's address bar and ENTER, nothing happens – eMi Jan 09 '15 at 11:28
  • 1
    @eMi I have IE10 here, and it does not let me paste the `javascript:` part, I have to type it manually. Maybe that's what happens. Double-check what is pasted. – Johnny5 Jan 14 '15 at 16:11
  • 1
    On Google Chrome (at least as of v44.0.2403.155) on Mac OSX, the bookmarklet by @Johnny5 does not result in a plain text page containing the source of the opener, but Chrome attempts to render the HTML, but without CSS, from the look of it. – Dave Land Aug 14 '15 at 15:47
  • @Johnny5 might be worth mentioning as a note in the answer that `javascript:` gets cut off when doing copy/paste in some browsers. Just had that issue in Chrome. – Bryan Oct 30 '15 at 18:08
  • the url of the post was changed and it is now [http://old.itauthor.com/2006/12/06/view-generated-source-in-internet-explorer/](http://old.itauthor.com/2006/12/06/view-generated-source-in-internet-explorer/) – lucky boost Nov 25 '15 at 15:42
12

If you load the document in Chrome, the Developer|Elements view will show you the HTML as fiddled by your JS code. It's not directly HTML text and you have to open (unfold) any elements of interest, but you effectively get to inspect the generated HTML.

Carl Smotricz
  • 66,391
  • 18
  • 125
  • 167
  • 11
    In Google Chrome, in Inspect Element, you can right click on any element and "Copy as HTML" – JasonPlutext Apr 02 '10 at 00:11
  • 3
    @Jason Thank you so much for this. Right-clicking on the element and choosing "Copy as HTML" gave me exactly what I needed in Chrome today. – DaveGauer Nov 28 '11 at 20:58
11

In the Web Developer Toolbar, have you tried the Tools -> Validate HTML or Tools -> Validate Local HTML options?

The Validate HTML option sends the url to the validator, which works well with publicly facing sites. The Validate Local HTML option sends the current page's HTML to the validator, which works well with pages behind a login, or those that aren't publicly accessible.

You may also want to try View Source Chart (also as FireFox add-on). An interesting note there:

Q. Why does View Source Chart change my XHTML tags to HTML tags?

A. It doesn't. The browser is making these changes, VSC merely displays what the browser has done with your code. Most common: self closing tags lose their closing slash (/). See this article on Rendered Source for more information (archive.org).

Andris
  • 921
  • 7
  • 14
Forgotten Semicolon
  • 13,909
  • 2
  • 51
  • 61
6

Using the Firefox Web Developer Toolbar (https://addons.mozilla.org/en-US/firefox/addon/60)

Just go to View Source -> View Generated Source

I use it all the time for the exact same thing.

lewsid
  • 1,900
  • 2
  • 17
  • 19
  • And I now see your edit where you cite the Doctype issue with the Toolbar. That's a fair criticism and I have nothing else to suggest. – lewsid Nov 17 '09 at 19:00
  • 3
    Works great and is now built right into vanilla Firefox. Ctrl+A, right-click, E. Also, see the excellent bookmarklet that Johnny5 found. – Jon Coombs Jan 03 '15 at 22:11
  • In Firefox: right-click on page with the generated content you want to view, then Web Developer > View Source > View Generated Source – Mark Gavagan Aug 02 '16 at 21:22
5

This is an old question, and here's an old answer that has once worked flawlessly for me for many years, but doesn't any more, at least not as of January 2016:

The "Generated Source" bookmarklet from SquareFree does exactly what you want -- and, unlike the otherwise fine "old gold" from @Johnny5, displays as source code (rather than being rendered normally by the browser, at least in the case of Google Chrome on Mac):

https://www.squarefree.com/bookmarklets/webdevel.html#generated_source

Unfortunately, it behaves just like the "old gold" from @Johnny5: it does not show up as source code any more. Sorry.

Dave Land
  • 2,257
  • 1
  • 18
  • 21
5

I had the same problem, and I've found here a solution:

http://ubuntuincident.wordpress.com/2011/04/15/scraping-ajax-web-pages/

So, to use Crowbar, the tool from here:

http://simile.mit.edu/wiki/Crowbar (now (2015-12) 404s)
wayback machine link:
http://web.archive.org/web/20140421160451/http://simile.mit.edu/wiki/Crowbar

It gave me the faulty, invalid HTML.

albert
  • 8,112
  • 3
  • 47
  • 63
adamvagyok
  • 165
  • 1
  • 2
  • 8
  • Check out the other parts of this series too: [Part 2](http://ubuntuincident.wordpress.com/2011/09/20/scraping-ajax-web-pages-part-2/), [Part 3](http://ubuntuincident.wordpress.com/2011/11/08/scraping-ajax-web-pages-part-3/). – Jabba Feb 17 '12 at 22:37
  • crowbar no longer seems to be there – Mousey Aug 15 '15 at 12:37
  • Not too user-friendly, but still can be downloaded through SVN: http://devres.zoomquiet.io/data/20110810165553/index.html – adamvagyok Aug 16 '15 at 13:43
4

alert(document.documentElement.outerHTML);

JohnnyFaldo
  • 4,121
  • 4
  • 19
  • 29
4

Check out "View Rendered Source" chrome extension:

https://chrome.google.com/webstore/detail/view-rendered-source/ejgngohbdedoabanmclafpkoogegdpob/

user882134
  • 279
  • 3
  • 16
4

In Firefox, just ctrl-a (select everything on the screen) then right click "View Selection Source". This captures any changes made by JavaScript to the DOM.

Mike_K
  • 9,010
  • 5
  • 20
  • 27
3

In the elements tab, right click the html node > copy > copy element - then paste into an editor.

As has been mentioned above, once the source has been converted into a DOM tree, the original source no longer exists in the browser. Any changes you make will be to the DOM, not the source.

However, you can parse the modified DOM back into HTML, letting you see the "generated source".

  1. In Chrome, open the developer tools and click the elements tab.
  2. Right click the HTML element.
  3. Choose copy > copy element.
  4. Paste into an editor.

You can now see the current DOM as an HTML page.

This is not the full DOM

Note that the DOM cannot be fully represented by an HTML document. This is because the DOM has many more properties than the HTML has attributes. However this will do a reasonable job.

superluminary
  • 47,086
  • 25
  • 151
  • 148
3

Why not type this is the urlbar?

javascript:alert(document.body.innerHTML)
Mike
  • 31
  • 1
2

I think IE dev tools (F12) has; View > Source > DOM (Page)

You would need to copy and paste the DOM and save it to send to the validator.

Will Hancock
  • 1,240
  • 4
  • 18
  • 27
  • You may also want to; File > Customise Internet Explorers view source > Notepad for easy saving when you do the above. – Will Hancock Mar 26 '12 at 15:22
1

The below javascript code snippet will get you the complete ajax rendered HTML generated source. Browser independent one. Enjoy :)

function outerHTML(node){
    // if IE, Chrome take the internal method otherwise build one as lower versions of firefox
        //does not support element.outerHTML property
  return node.outerHTML || (
      function(n){
          var div = document.createElement('div'), h;
          div.appendChild( n.cloneNode(true) );
          h = div.innerHTML;
          div = null;
          return h;
      })(node);
  }


 var outerhtml = outerHTML(document.getElementsByTagName('html')[0]);
var node = document.doctype;
var doctypestring="";
if(node)
{
     // IE8 and below does not have document.doctype and you will get null if you access it.

 doctypestring = "<!DOCTYPE "
         + node.name
         + (node.publicId ? ' PUBLIC "' + node.publicId + '"' : '')
         + (!node.publicId && node.systemId ? ' SYSTEM' : '') 
         + (node.systemId ? ' "' + node.systemId + '"' : '')
         + '>';
         }
         else

         {

             // for IE8 and below you can access doctype like this

         doctypestring = document.all[0].text;
         }
doctypestring +outerhtml ;
Sathish
  • 409
  • 8
  • 24
  • I think this would need specific instructions as to how to use it. I assume you'd paste the code into the existing page, but where would the output go? – Jon Coombs Jan 03 '15 at 21:59
1

Only thing i found is the BetterSource extension for Safari this will show you the manipulated source of the document only downside is nothing remotely like it for Firefox

0

I was able to solve a similar issue by logging the results of the ajax call to the console. This was the html returned and I could easily see any issues that it had.

in my .done() function of my ajax call I added console.log(results) so I could see the html in the debugger console.

function GetReversals() {
    $("#getReversalsLoadingButton").removeClass("d-none");
    $("#getReversalsButton").addClass("d-none");

    $.ajax({
        url: '/Home/LookupReversals',
        data: $("#LookupReversals").serialize(),
        type: 'Post',
        cache: false
    }).done(function (result) {
        $('#reversalResults').html(result);
        console.log(result);
    }).fail(function (jqXHR, textStatus, errorThrown) {
        //alert("There was a problem getting results.  Please try again. " + jqXHR.responseText + " | " + jqXHR.statusText);
        $("#reversalResults").html("<div class='text-danger'>" + jqXHR.responseText + "</div>");
    }).always(function () {
        $("#getReversalsLoadingButton").addClass("d-none");
        $("#getReversalsButton").removeClass("d-none");
    });
}
ebarke
  • 1
  • 1
  • 3
  • @erbarke, could you elaborate more on your answer explain in more details (code, detailed action flow)? – Artem Sep 24 '18 at 13:06