Bagaimana cara mendapatkan seluruh dokumen HTML sebagai string?

237

Apakah ada cara di JS untuk mendapatkan seluruh HTML dalam tag html , sebagai string?

document.documentElement.??
Kilat
sumber
10
Satu-satunya jawaban yang benar: stackoverflow.com/questions/817218/… ( hentikan memilih-suara dalam / luar jawabanHTHTML, mereka TIDAK menyediakan seluruh sumber! )
John
2
document.body.parentElement.innerHTML
Program Redwolf
@ John apa yang tidak mereka sediakan?
bluejayke

Jawaban:

320

MS menambahkan outerHTMLdan innerHTMLproperti beberapa waktu lalu.

Menurut MDN , outerHTMLdidukung di Firefox 11, Chrome 0.2, Internet Explorer 4.0, Opera 7, Safari 1.3, Android, Firefox Mobile 11, IE Mobile, Opera Mobile, dan Safari Mobile. outerHTMLada dalam spesifikasi Parsing dan Serialisasi DOM .

Lihat quirksmode untuk kompatibilitas browser untuk apa yang akan bekerja untuk Anda. Semua dukungan innerHTML.

var markup = document.documentElement.innerHTML;
alert(markup);
Colin Burnett
sumber
28
outerHTML tidak mendapatkan DOCTYPE.
CMCDragonkai
2
bekerja seperti pesona! Terima kasih! apakah ada cara untuk mendapatkan ukuran semua / semua file yang terhubung ke dokumen juga termasuk file js dan css?
www139
@ CMCDragonkai: Anda bisa mendapatkan DOCTYPE secara terpisah dan menambahkannya ke string markup. Tidak ideal, saya tahu, tapi mungkin.
Mike Branski
76

Anda dapat melakukan

new XMLSerializer().serializeToString(document)

di browser yang lebih baru dari IE 9

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

Erik Aigner
sumber
5
Ini adalah jawaban yang benar pertama berdasarkan tanggal / waktu perangko. Bagian dari halaman seperti deklarasi XML tidak akan disertakan dan browser akan memanipulasi kode ketika menggunakan "jawaban" lainnya. Ini adalah satu - satunya posting yang harus dipilih (dos diposting tiga hari kemudian). Orang-orang perlu memperhatikan!
John
2
Ini tidak sepenuhnya benar karena serializeToString melakukan penyandian HTML. Misalnya jika kode Anda berisi gaya yang mendefinisikan font seperti "Times New Roman", Times, serif tanda kutip akan mendapatkan html disandikan. Mungkin itu tidak penting bagi sebagian dari Anda tetapi bagi saya itu adalah ...
Marko
3
@John well OP sebenarnya meminta "seluruh HTML dalam tag html". Dan jawaban terbaik yang dipilih oleh Colin Burnett tidak mencapai ini. Jawaban khusus ini (Erik) akan mencakup tag html dan doctype. Yang mengatakan, ini benar-benar berlian di kasar untuk saya dan persis apa yang saya cari! Komentar Anda juga membantu karena itu membuat saya menghabiskan lebih banyak waktu dengan jawaban ini, jadi terima kasih :)
evanrmurphy
2
Saya pikir orang harus berhati-hati dengan yang satu ini, khususnya karena mengembalikan nilai yang bukan html aktual yang diterima browser Anda. Dalam kasus saya, itu menambahkan atribut ke htmltag yang server tidak pernah benar-benar mengirim :(
onassar
1
Ini didukung di setiap browser. Bagaimana dukungan browser yang buruk ini?
Erik Aigner
44

Saya percaya document.documentElement.outerHTMLharus mengembalikannya untuk Anda.

Menurut MDN , outerHTMLdidukung di Firefox 11, Chrome 0.2, Internet Explorer 4.0, Opera 7, Safari 1.3, Android, Firefox Mobile 11, IE Mobile, Opera Mobile, dan Safari Mobile. outerHTMLada dalam spesifikasi Parsing dan Serialisasi DOM .

Halaman MSDN di outerHTMLproperti mencatat bahwa didukung di IE 5+. Tautan jawaban Colin ke halaman quirksmode W3C, yang menawarkan perbandingan kompatibilitas lintas-browser yang baik (untuk fitur DOM lainnya juga).

Noldorin
sumber
Tidak semua browser mendukung ini.
Colin Burnett
@Colin: Ya, poin bagus. Dari pengalaman, saya sepertinya ingat bahwa baik IE 6+ dan Firefox mendukungnya, meskipun halaman quirksmode yang Anda tautkan menunjukkan sebaliknya ...
Noldorin
Firefox tidak mendukung OuterHTML. Ini adalah hak milik IE. developer.mozilla.org/En/…
Jesse Dearing
4
Apakah ada cara untuk mendapatkan semuanya termasuk DOCTYPE dan tag html?
trusktr
1
Milik saya yang pertama, sebenarnya. : P
Noldorin
40

Saya mencoba berbagai jawaban untuk melihat apa yang dikembalikan. Saya menggunakan Chrome versi terbaru.

Saran itu document.documentElement.innerHTML;dikembalikan<head> ... </body>

Saran Gaby document.getElementsByTagName('html')[0].innerHTML;kembali sama.

Saran document.documentElement.outerHTML;dikembalikan <html><head> ... </body></html> yang semuanya terpisah dari 'DOCTYPE'.

Anda dapat mengambil objek doctype dengan document.doctype; Ini mengembalikan objek, bukan string, jadi jika Anda perlu mengekstrak detail sebagai string untuk semua doctypes hingga dan termasuk HTML5 itu dijelaskan di sini: Dapatkan DocType dari HTML sebagai string dengan Javascript

Saya hanya ingin HTML5, jadi berikut ini sudah cukup bagi saya untuk membuat seluruh dokumen:

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

paulo62
sumber
6
Ini adalah jawaban yang paling lengkap dan harus diterima. Pada 2016, kompatibilitas browser selesai, dan menyebutkannya secara detail (seperti dalam jawaban yang saat ini diterima) tidak lagi diperlukan.
Dan Dascalescu
10

Anda juga dapat melakukan:

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

Anda tidak akan mendapatkan tag Doctype atau html, tetapi yang lainnya ...

Hakan
sumber
5
document.documentElement.outerHTML
Brian Campbell
sumber
1
Tidak semua browser mendukung ini.
Colin Burnett
2
Didukung di Firefox 11, Chrome 0.2, Internet Explorer 4.0, Opera 7, Safari 1.3, Android, Firefox Mobile 11, IE Mobile, Opera Mobile, dan Safari Mobile ( MDN ). outerHTMLada dalam spesifikasi Parsing dan Serialisasi DOM .
XP1
Jawaban Colin lebih detail.
Dan Dascalescu
4

HANYA MUNGKIN IE:

>     webBrowser1.DocumentText

untuk FF naik dari 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));

dapat bekerja di FF. (Memperlihatkan 300 karakter SANGAT PERTAMA dari awal teks sumber SANGAT, sebagian besar doctype-defs.)

TAPI waspada, bahwa "Save As" normal-Dialog FF MUNGKIN TIDAK menyimpan keadaan halaman saat ini, melainkan X / h / tml-sumber-teks yang aslinya dimuat !! (POST-up ss ke beberapa temp-file dan redirect ke yang mungkin memberikan teks sumber yang dapat disimpan DENGAN perubahan / suntingan sebelum dibuat untuk itu.)

Meskipun FF mengejutkan dengan pemulihan yang baik pada "kembali" dan dimasukkannya NICE status / nilai pada "Simpan (sebagai) ..." untuk BIDANG input-seperti, textarea dll., Bukan pada elemen dalam contenteditable / designMode ...

Jika BUKAN xhtml- resp. xml-file (tipe mime, BUKAN hanya nama file-ekstensi!), orang dapat menggunakan document.open/write/close untuk SETELAH appr. konten ke layer sumber, yang akan disimpan pada dialog save pengguna dari File / Save me of FF. lihat: http://www.w3.org/MarkUp/2004/xhtml-faq#docwrite resp.

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

Netral untuk pertanyaan X (ht) ML, coba "view-source: http: // ..." sebagai nilai src-attrib dari iframe (skrip buatan !?), - untuk mengakses iframe- dokumen dalam FF:

<iframe-elementnode>.contentDocument, lihat google "mdn contentDocument" untuk appr. anggota, seperti 'textContent' misalnya. 'Sudah bertahun-tahun yang lalu dan tidak suka merangkak untuk itu. Jika masih sangat mendesak, sebutkan ini, bahwa saya harus menyelam ...

dos
sumber
2
document.documentElement.innerHTML
cherouvim
sumber
Ini tidak mengembalikan <html ...>tag.
Dan Dascalescu
1

Gunakan document.documentElement.

Pertanyaan yang sama dijawab di sini: https://stackoverflow.com/a/7289396/2164160

Veer En
sumber
Pertanyaan itu harus ditutup sebagai duplikat dari pertanyaan ini, yang jauh lebih tua. Bagaimanapun, bagian yang menarik adalah bahwa Anda perlu .outerHTMLdan untuk mendapatkan document.doctype, dan jawaban yang paling lengkap adalah milik Paolo .
Dan Dascalescu
1

Untuk juga mendapatkan hal-hal di luar <html>...</html>, yang paling penting <!DOCTYPE ...>deklarasi, Anda bisa berjalan melalui document.childNodes, mengubah masing-masing menjadi string:

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}`)
    }
}

Saya menerbitkan kode ini sebagai document-outerhtml pada npm.


sunting Catatan kode di atas tergantung pada suatu fungsi doctypeToString; implementasinya bisa sebagai berikut (kode di bawah ini diterbitkan pada npm sebagai 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
sumber
0

Saya selalu menggunakan

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

Mungkin bukan cara yang benar tetapi saya bisa memahaminya ketika saya melihatnya.

gaby de wilde
sumber
Ini tidak benar karena tidak akan mengembalikan <html...>tag.
Dan Dascalescu
0

Saya hanya perlu html doctype dan harus berfungsi dengan baik di IE11, Edge dan Chrome. Saya menggunakan kode di bawah ini berfungsi dengan baik.

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');
    }
}

dan dalam anchor tag Anda gunakan seperti ini.

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

Contoh

    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
sumber
0

Saya menggunakan outerHTMLelemen ( <html>wadah utama ), dan XMLSerializeruntuk hal lain termasuk <!DOCTYPE>, komentar acak di luar <html>wadah, atau apa pun yang mungkin ada di sana. Tampaknya spasi putih tidak disimpan di luar <html>elemen, jadi saya menambahkan baris baru secara default dengan 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
sumber
-2

Anda harus mengulang melalui childNodes dokumen dan mendapatkan konten outerHTML.

di VBA terlihat seperti ini

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

menggunakan ini, memungkinkan Anda untuk mendapatkan semua elemen halaman web termasuk <! DOCTYPE> node jika ada

milevyo
sumber
-9

Cara yang benar sebenarnya:

webBrowser1.DocumentText

Damiano
sumber