Jak uzyskać cały dokument HTML jako ciąg?

236

Czy jest sposób w JS, aby uzyskać cały HTML w tagach HTML jako ciąg?

document.documentElement.??
Błysk
źródło
10
Jedyna poprawna odpowiedź: stackoverflow.com/questions/817218/… ( zatrzymaj głosowanie w górę odpowiedzi wewnętrzne / zewnętrzne HTML, NIE zawierają one całego źródła! )
Jan
2
document.body.parentElement.innerHTML
Programy Redwolf
@John, czego oni nie dostarczają?
bluejayke

Odpowiedzi:

319

MS dodał outerHTMLi innerHTMLwłaściwości jakiś czas temu.

Według MDN , outerHTMLjest obsługiwany w Firefox 11, Chrome 0.2, Internet Explorer 4.0, Opera 7, Safari 1.3, Android, Firefox Mobile 11, IE Mobile, Opera Mobile i Safari Mobile. outerHTMLznajduje się w specyfikacji analizowania i serializacji DOM .

Zobacz tryb quirksmode w celu uzyskania informacji na temat kompatybilności przeglądarki. Wszystkie wsparcie innerHTML.

var markup = document.documentElement.innerHTML;
alert(markup);
Colin Burnett
źródło
28
outerHTML nie otrzymuje doctype.
CMCDragonkai
2
działało jak urok! Dziękuję Ci! czy jest jakiś sposób, aby uzyskać rozmiar dowolnego / wszystkich plików połączonych z dokumentem, w tym plików js i css?
www139
@CMCDragonkai: Możesz uzyskać doctype osobno i dołączyć go do ciągu znaczników. Nie wiem, wiem, ale możliwe.
Mike Branski
76

Możesz to zrobić

new XMLSerializer().serializeToString(document)

w przeglądarkach nowszych niż IE 9

Zobacz https://caniuse.com/#feat=xml-serializer

Erik Aigner
źródło
5
To była pierwsza poprawna odpowiedź według znaczników daty / godziny. Części strony, takie jak deklaracja XML, nie zostaną uwzględnione, a przeglądarki będą manipulować kodem podczas korzystania z innych „odpowiedzi”. To jedyny post, który powinien zostać poddany głosowaniu (dos został opublikowany trzy dni później). Ludzie muszą zwracać uwagę!
Jan
2
Nie jest to do końca poprawne, ponieważ serializeToString wykonuje kodowanie HTML. Na przykład jeśli kod zawiera style definiujące czcionki, takie jak „Times New Roman”, Times, serif, cudzysłowy zostaną zakodowane w formacie HTML. Być może nie jest to ważne dla niektórych z was, ale dla mnie jest to ...
Marko
3
@John, OP właściwie prosi o „cały HTML w tagach HTML”. I wybrana najlepsza odpowiedź Colina Burnetta to osiąga. Ta konkretna odpowiedź (Erika) będzie zawierać tagi HTML i doctype. To powiedziawszy, był to dla mnie absolutnie nieoszlifowany diament i dokładnie to, czego szukałem! Twój komentarz również pomógł, ponieważ dzięki temu spędziłem więcej czasu z tą odpowiedzią, więc dziękuję :)
evanrmurphy
2
Myślę, że ludzie powinni być ostrożni z tym, szczególnie dlatego, że zwraca wartość, która nie jest rzeczywistym plikiem HTML otrzymywanym przez przeglądarkę. W moim przypadku dodało atrybuty do htmlznacznika, którego serwer tak naprawdę nigdy nie wysłał :(
onassar
1
Jest obsługiwany w każdej przeglądarce. Jak działa ta słaba obsługa przeglądarki?
Erik Aigner,
44

Wierzę, że document.documentElement.outerHTMLpowinien ci to zwrócić.

Według MDN , outerHTMLjest obsługiwany w Firefox 11, Chrome 0.2, Internet Explorer 4.0, Opera 7, Safari 1.3, Android, Firefox Mobile 11, IE Mobile, Opera Mobile i Safari Mobile. outerHTMLznajduje się w specyfikacji analizowania i serializacji DOM .

Strona MSDN outerHTMLwłaściwości wskazuje, że jest obsługiwana w IE 5+. Odpowiedź Colina prowadzi do strony trybu quirksmode W3C, która oferuje dobre porównanie kompatybilności z różnymi przeglądarkami (także dla innych funkcji DOM).

Noldorin
źródło
Nie wszystkie przeglądarki obsługują to.
Colin Burnett
@Colin: Tak, dobra uwaga. Z doświadczenia wydaje mi się, że pamiętam, że zarówno IE 6+, jak i Firefox go obsługują, chociaż strona trybu quirksmode, którą podłączyłeś, sugeruje inaczej ...
Noldorin
Firefox nie obsługuje OuterHTML. Jest zastrzeżony dla IE. developer.mozilla.org/En/…
Jesse Dearing
4
Czy istnieje sposób na uzyskanie wszystkiego, w tym tagów doctype i html?
trusktr
1
Mój był właściwie pierwszy. : P
Noldorin
40

Próbowałem różnych odpowiedzi, aby zobaczyć, co jest zwracane. Korzystam z najnowszej wersji Chrome.

Sugestia document.documentElement.innerHTML;wróciła<head> ... </body>

Sugestia Gaby document.getElementsByTagName('html')[0].innerHTML;zwróciła to samo.

document.documentElement.outerHTML;Wróciła sugestia, <html><head> ... </body></html> która jest wszystkim oprócz „doctype”.

Możesz pobrać obiekt doctype za pomocą document.doctype; To zwraca obiekt, a nie ciąg, więc jeśli chcesz wyodrębnić szczegóły jako ciągi dla wszystkich typów dokumentów do HTML5 włącznie, jest to opisane tutaj: Pobierz DocType kodu HTML jako ciąg z Javascriptem

Chciałem tylko HTML5, więc wystarczyło, że utworzyłem cały dokument:

alert('<!DOCTYPE HTML>' + '\n' + document.documentElement.outerHTML);

paulo62
źródło
6
To jest najbardziej kompletna odpowiedź i powinna zostać zaakceptowana. Od 2016 roku kompatybilność z przeglądarkami jest kompletna, a szczegółowe wzmiankowanie o niej (jak w obecnie akceptowanej odpowiedzi) nie jest już konieczne.
Dan Dascalescu,
10

Możesz także:

document.getElementsByTagName('html')[0].innerHTML

Nie otrzymasz tagu Doctype ani html, ale wszystko inne ...

Hakan
źródło
5
document.documentElement.outerHTML
Brian Campbell
źródło
1
Nie wszystkie przeglądarki obsługują to.
Colin Burnett
2
Obsługiwane w Firefox 11, Chrome 0.2, Internet Explorer 4.0, Opera 7, Safari 1.3, Android, Firefox Mobile 11, IE Mobile, Opera Mobile i Safari Mobile ( MDN ). outerHTMLznajduje się w specyfikacji analizowania i serializacji DOM .
XP1,
Odpowiedź Colina jest bardziej szczegółowa.
Dan Dascalescu,
4

PRAWDOPODOBNIE TYLKO IE:

>     webBrowser1.DocumentText

dla FF od 1.0:

//serialize current DOM-Tree incl. changes/edits to ss-variable
var ns = new XMLSerializer();
var ss= ns.serializeToString(document);
alert(ss.substr(0,300));

może działać w FF. (Pokazuje BARDZO PIERWSZE 300 znaków od BARDZO początku tekstu źródłowego, głównie doctype-defs.)

ALE pamiętaj, że normalny „Zapisz jako” -Dialog FF MOGĄ NIE zapisać bieżącego stanu strony, a raczej oryginalnie załadowanego X / h / tml-source-text !! (POST-up ss do jakiegoś pliku tymczasowego i przekierowanie do niego może dostarczyć zapisywalny tekst źródłowy ze zmianami / edycjami wcześniej dokonanymi).

Chociaż FF zaskakuje dobrym odzyskiem na „wstecz” i NICJĄ zawierającą stany / wartości w „Zapisz (as) ...” dla FIELDS podobnych do danych wejściowych, pola tekstowego itp., A nie na elementach w contentediable / designMode ...

Jeśli NIE, xhtml-resp. plik xml (typ MIME, NIE tylko rozszerzenie pliku!), można użyć document.open/write/close, aby USTAWIĆ appr. zawartość do warstwy źródłowej, która zostanie zapisana w oknie dialogowym zapisu użytkownika z menu Plik / Zapisz FF. patrz: http://www.w3.org/MarkUp/2004/xhtml-faq#docwrite i .

https://developer.mozilla.org/en-US/docs/Web/API/document.write

Neutralnie na pytania dotyczące X (ht) ML, spróbuj użyć „view-source: http: // ...” jako wartości atrybutu src atrybutu iframe (wykonanego w skrypcie !?), - aby uzyskać dostęp do iframe- dokument w FF:

<iframe-elementnode>.contentDocument, zobacz google „mdn contentDocument” dla ok. członkowie, na przykład „textContent”. Dostałem to lata temu i nie lubię się czołgać. Jeśli nadal pilna potrzeba, wspomnij o tym, że muszę nurkować ...

dos
źródło
2
document.documentElement.innerHTML
Cherouvim
źródło
To nie zwraca <html ...>tagu.
Dan Dascalescu,
1

Zastosowanie document.documentElement.

To samo pytanie, na które odpowiedziano tutaj: https://stackoverflow.com/a/7289396/2164160

Veer En
źródło
To pytanie powinno zostać zamknięte jako niemal duplikat tego, który jest znacznie starszy. W każdym razie interesującą częścią jest to, że potrzebujesz .outerHTMLi aby uzyskać document.doctype, a najbardziej kompletną odpowiedzią jest odpowiedź Paola .
Dan Dascalescu,
1

Aby uzyskać także rzeczy poza deklaracją, co <html>...</html>najważniejsze <!DOCTYPE ...>, możesz przejść przez document.childNodes, zamieniając każdy w ciąg znaków:

const html = [...document.childNodes]
    .map(node => nodeToString(node))
    .join('\n') // could use '' instead, but whitespace should not matter.

function nodeToString(node) {
    switch (node.nodeType) {
        case node.ELEMENT_NODE:
            return node.outerHTML
        case node.TEXT_NODE:
            // Text nodes should probably never be encountered, but handling them anyway.
            return node.textContent
        case node.COMMENT_NODE:
            return `<!--${node.textContent}-->`
        case node.DOCUMENT_TYPE_NODE:
            return doctypeToString(node)
        default:
            throw new TypeError(`Unexpected node type: ${node.nodeType}`)
    }
}

Ten kod opublikowałem jako dokument-zewnętrzny_html na npm.


edytuj Uwaga powyższy kod zależy od funkcji doctypeToString; jego implementacja może wyglądać następująco (poniższy kod jest opublikowany na npm jako doctype-to-string ):

function doctypeToString(doctype) {
    if (doctype === null) {
        return ''
    }
    // Checking with instanceof DocumentType might be neater, but how to get a
    // reference to DocumentType without assuming it to be available globally?
    // To play nice with custom DOM implementations, we resort to duck-typing.
    if (!doctype
        || doctype.nodeType !== doctype.DOCUMENT_TYPE_NODE
        || typeof doctype.name !== 'string'
        || typeof doctype.publicId !== 'string'
        || typeof doctype.systemId !== 'string'
    ) {
        throw new TypeError('Expected a DocumentType')
    }
    const doctypeString = `<!DOCTYPE ${doctype.name}`
        + (doctype.publicId ? ` PUBLIC "${doctype.publicId}"` : '')
        + (doctype.systemId
            ? (doctype.publicId ? `` : ` SYSTEM`) + ` "${doctype.systemId}"`
            : ``)
        + `>`
    return doctypeString
}

Gerben
źródło
0

Zawsze używam

document.getElementsByTagName('html')[0].innerHTML

Prawdopodobnie nie jest to właściwa droga, ale rozumiem ją, kiedy ją widzę.

gaby de wilde
źródło
Jest to nieprawidłowe, ponieważ nie zwróci <html...>tagu.
Dan Dascalescu
0

Potrzebuję tylko html doctype i powinien działać dobrze w IE11, Edge i Chrome. Użyłem poniżej kodu, działa dobrze.

function downloadPage(element, event) {
    var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);

    if ((navigator.userAgent.indexOf("MSIE") != -1) || (!!document.documentMode == true)) {
        document.execCommand('SaveAs', '1', 'page.html');
        event.preventDefault();
    } else {
        if(isChrome) {
            element.setAttribute('href','data:text/html;charset=UTF-8,'+encodeURIComponent('<!doctype html>' + document.documentElement.outerHTML));
        }
        element.setAttribute('download', 'page.html');
    }
}

i użyj tego w tagu kotwicy.

<a href="#" onclick="downloadPage(this,event);" download>Download entire page.</a>

Przykład

    function downloadPage(element, event) {
    	var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
    
    	if ((navigator.userAgent.indexOf("MSIE") != -1) || (!!document.documentMode == true)) {
    		document.execCommand('SaveAs', '1', 'page.html');
    		event.preventDefault();
    	} else {
    		if(isChrome) {
                element.setAttribute('href','data:text/html;charset=UTF-8,'+encodeURIComponent('<!doctype html>' + document.documentElement.outerHTML));
    		}
    		element.setAttribute('download', 'page.html');
    	}
    }
I just need doctype html and should work fine in IE11, Edge and Chrome. 

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

<p>
<a href="#" onclick="downloadPage(this,event);"  download><h2>Download entire page.</h2></a></p>

<p>Some image here</p>

<p><img src="https://placeimg.com/250/150/animals"/></p>

kiranvj
źródło
0

Używam outerHTMLdo elementów (głównego <html>kontenera) i XMLSerializerdo wszystkiego innego, w tym <!DOCTYPE>losowych komentarzy poza <html>kontenerem lub cokolwiek innego, co może tam być. Wygląda na to, że spacje nie są zachowywane poza <html>elementem, więc domyślnie dodam nowe linie za pomocą sep="\n".

function get_document_html(sep="\n") {
    let html = "";
    let xml = new XMLSerializer();
    for (let n of document.childNodes) {
        if (n.nodeType == Node.ELEMENT_NODE)
            html += n.outerHTML + sep;
        else
            html += xml.serializeToString(n) + sep;
    }
    return html;
}

console.log(get_document_html().slice(0, 200));

Sam Watkins
źródło
-2

Musisz iterować dokument childNodes i pobierać treść outerHTML.

w VBA wygląda to tak

For Each e In document.ChildNodes
    Put ff, , e.outerHTML & vbCrLf
Next e

użycie tego pozwala uzyskać wszystkie elementy strony internetowej, w tym węzeł <! DOCTYPE>, jeśli istnieje

milevyo
źródło
-9

Właściwy sposób to w rzeczywistości:

webBrowser1.DocumentText

Damiano
źródło