วิธีรับ HTML เอกสารทั้งหมดเป็นสตริง?


236

มีวิธีใน JS เพื่อรับ HTML ทั้งหมดภายในแท็กhtmlเป็นสตริงหรือไม่

document.documentElement.??

10
คำตอบที่ถูกต้องเพียงข้อเดียว: stackoverflow.com/questions/817218/… ( หยุดตอบคำถามภายใน / ภายนอกHTMLคำตอบพวกเขาไม่ได้ให้ข้อมูลทั้งหมด! )
John

2
document.body.parentElement.innerHTML
โปรแกรม Redwolf

@John พวกเขาไม่ได้ให้อะไร
bluejayke

คำตอบ:


319

MS ได้เพิ่มคุณสมบัติouterHTMLและinnerHTMLบางเวลาที่ผ่านมา

ตามMDN , outerHTMLได้รับการสนับสนุนใน Firefox 11, Chrome 0.2, Internet Explorer 4.0, Opera 7, Safari 1.3, Android, Firefox มือถือ 11 IE Mobile, Opera Mobile และ Safari มือถือ outerHTMLอยู่ในDOM แยกและเป็นอันดับข้อกำหนด

ดูquirksmodeสำหรับความเข้ากันได้ของเบราว์เซอร์สำหรับสิ่งที่เหมาะกับคุณ innerHTMLการสนับสนุนทั้งหมด

var markup = document.documentElement.innerHTML;
alert(markup);

28
outerHTML ไม่ได้รับประเภทเอกสาร
CMCDragonkai

2
ทำงานเหมือนจับใจ! ขอบคุณ! มีวิธีใดบ้างในการรับขนาดของไฟล์ใด ๆ / ทั้งหมดที่เชื่อมโยงกับเอกสารรวมถึงไฟล์ js และ css
www139

@CMCDragonkai: คุณสามารถแยกประเภท doctypeและผนวกเข้ากับสตริงมาร์กอัป ไม่เหมาะฉันรู้ แต่เป็นไปได้
Mike Branski

76

คุณทำได้

new XMLSerializer().serializeToString(document)

ในเบราว์เซอร์ใหม่กว่า IE 9

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


5
นี่เป็นคำตอบแรกที่ ถูกต้องตามการประทับวันที่ / เวลา บางส่วนของหน้าเช่นประกาศ XML จะไม่รวมอยู่และเบราว์เซอร์จะจัดการรหัสเมื่อใช้ "คำตอบ" อื่น ๆ นี่เป็นเพียงโพสต์เดียวที่ควรได้รับการโหวต (dos โพสต์ในอีกสามวันต่อมา) ผู้คนต้องใส่ใจ!
John

2
สิ่งนี้ไม่ถูกต้องอย่างสิ้นเชิงเนื่องจาก serializeToString ทำการเข้ารหัส HTML ตัวอย่างเช่นหากรหัสของคุณมีสไตล์ที่กำหนดแบบอักษรเช่น "Times New Roman", Times, serif เครื่องหมายคำพูดจะได้รับการเข้ารหัส html บางทีนั่นอาจไม่สำคัญสำหรับคุณบางคน แต่สำหรับฉันมันเป็น ...
Marko

3
@John OP จริง ๆ ถามหา "HTML ทั้งหมดภายในแท็ก html" และคำตอบที่ดีที่สุดที่เลือกโดย Colin Burnett ก็ทำได้เช่นนี้ คำตอบเฉพาะนี้ (ของ Erik) จะรวมแท็ก html และประเภทของเอกสาร ที่กล่าวว่านี่เป็นเพชรที่หยาบสำหรับฉันและสิ่งที่ฉันกำลังมองหา! ความคิดเห็นของคุณก็ช่วยด้วยเพราะมันทำให้ฉันใช้เวลากับคำตอบนี้มากขึ้นขอบคุณ :)
evanrmurphy

2
ฉันคิดว่าคนควรจะระมัดระวังกับสิ่งนี้โดยเฉพาะเพราะมันคืนค่าที่ไม่ใช่ html จริงที่เบราว์เซอร์ของคุณได้รับ ในกรณีของฉันมันเพิ่มคุณสมบัติให้กับhtmlแท็กที่เซิร์ฟเวอร์ไม่เคยส่งจริง :(
onassar

1
รองรับทุกเบราว์เซอร์ เบราว์เซอร์ที่ไม่ดีนี้รองรับอย่างไร
Erik Aigner

44

ฉันเชื่อว่าdocument.documentElement.outerHTMLควรคืนสิ่งนั้นให้คุณ

ตามMDN , outerHTMLได้รับการสนับสนุนใน Firefox 11, Chrome 0.2, Internet Explorer 4.0, Opera 7, Safari 1.3, Android, Firefox มือถือ 11 IE Mobile, Opera Mobile และ Safari มือถือ outerHTMLอยู่ในDOM แยกและเป็นอันดับข้อกำหนด

เพจ MSDN บนouterHTMLคุณสมบัติจะบันทึกว่าได้รับการสนับสนุนใน IE 5+ ลิงก์คำตอบของ Colin ไปยังหน้า W3C quirksmode ซึ่งมีการเปรียบเทียบความเข้ากันได้ของ cross-browser (สำหรับคุณสมบัติ DOM อื่น ๆ ด้วย)


ไม่ใช่ทุกเบราว์เซอร์ที่รองรับสิ่งนี้
Colin Burnett

@ Colin: ใช่จุดดี จากประสบการณ์ของผมดูเหมือนจะจำว่าทั้ง IE และ Firefox 6+ สนับสนุนมันแม้ว่าหน้า quirksmode ที่คุณเชื่อมโยงเห็นเป็นอย่างอื่น ...
Noldorin

Firefox ไม่รองรับ OuterHTML เป็นกรรมสิทธิ์ของ IE developer.mozilla.org/En/…
Jesse Dearing

4
มีวิธีในการรับทุกอย่างรวมถึง doctype และแท็ก html หรือไม่
trusktr

1
ฉันเป็นคนแรกจริง ๆ แล้ว : P
Noldorin

40

ฉันลองคำตอบต่าง ๆ เพื่อดูว่ามีอะไรกลับมา ฉันใช้ Chrome เวอร์ชันล่าสุด

คำแนะนำถูกdocument.documentElement.innerHTML;ส่งคืน<head> ... </body>

คำแนะนำของ Gaby document.getElementsByTagName('html')[0].innerHTML;กลับมาเหมือนเดิม

ข้อเสนอแนะที่document.documentElement.outerHTML;ส่งคืน<html><head> ... </body></html> ซึ่งเป็นทุกอย่างนอกเหนือจาก 'doctype'

คุณสามารถดึงข้อมูลวัตถุ doctype ด้วยdocument.doctype; นี้ส่งคืนวัตถุไม่ใช่สตริงดังนั้นหากคุณต้องการแยกรายละเอียดเป็นสตริงสำหรับ doctypes ทั้งหมดจนถึงและรวมถึง HTML5 อธิบายไว้ที่นี่: รับDocType ของ HTML เป็นสตริงด้วย Javascript

ฉันแค่ต้องการ HTML5 ดังนั้นต่อไปนี้ก็เพียงพอสำหรับฉันในการสร้างเอกสารทั้งหมด:

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


6
นี่คือคำตอบที่สมบูรณ์ที่สุดและควรได้รับการยอมรับ ในปี 2559 ความเข้ากันได้ของเบราว์เซอร์เสร็จสมบูรณ์และการกล่าวถึงในรายละเอียด (ตามคำตอบที่ยอมรับในปัจจุบัน) นั้นไม่จำเป็นอีกต่อไป
Dan Dascalescu

10

คุณยังสามารถทำสิ่งต่อไปนี้

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

คุณจะไม่ได้รับ Doctype หรือแท็ก html แต่อย่างอื่น ...


5
document.documentElement.outerHTML

1
ไม่ใช่ทุกเบราว์เซอร์ที่รองรับสิ่งนี้
Colin Burnett

2
รองรับ Firefox 11, Chrome 0.2, Internet Explorer 4.0, Opera 7, Safari 1.3, Android, Firefox Mobile 11, IE Mobile, Opera Mobile และ Safari Mobile ( MDN ) outerHTMLอยู่ในDOM แยกและเป็นอันดับข้อกำหนด
XP1

คำตอบของโคลินนั้นมีรายละเอียดมากกว่านี้
Dan Dascalescu

4

น่าจะเป็น IE เท่านั้น:

>     webBrowser1.DocumentText

สำหรับ FF เพิ่มขึ้นจาก 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));

อาจทำงานใน FF (แสดงให้เห็นถึง VERY FIRST 300 ตัวอักษรจากจุดเริ่มต้นของแหล่งที่มาข้อความมากส่วนใหญ่ doctype-defs)

แต่โปรดทราบว่า "บันทึกเป็น" ปกติ -Dialog ของ FF อาจไม่บันทึกสถานะปัจจุบันของหน้าเว็บแทนที่จะโหลด X / h / tml-source-text ดั้งเดิมทั้งหมด (POST-up ของ SS ไปที่ temp-file บางส่วนและเปลี่ยนเส้นทางไปยังที่อาจส่งมอบข้อความต้นฉบับที่บันทึกได้พร้อมกับการเปลี่ยนแปลง / การแก้ไขก่อนหน้านี้)

แม้ว่า FF ที่น่าประหลาดใจโดยการกู้คืนที่ดีใน "back" และการรวม NICE ของรัฐ / ค่าที่ "Save (as) ... " สำหรับ FIELDS ที่เหมือนอินพุท textareaฯลฯ ไม่ได้อยู่ในองค์ประกอบใน contenteditable / designMode ...

ถ้าไม่ใช่ xhtml- resp ไฟล์ xml (ประเภท mime ไม่ใช่แค่ชื่อไฟล์นามสกุล!) ไฟล์หนึ่งอาจใช้ document.open/write/close เพื่อตั้งค่า appr เนื้อหาไปยังเลเยอร์ต้นทางที่จะถูกบันทึกในกล่องโต้ตอบบันทึกของผู้ใช้จากเมนู File / Save menue ของ FF ดู: http://www.w3.org/MarkUp/2004/xhtml-faq#docwrite resp

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

เป็นกลางกับคำถามของ X (ht) ML ลองใช้ "view-source: http: // ... " เป็นค่าของ src-attrib ของ iframe (ทำสคริปต์ !?) - เพื่อเข้าถึง iframes- เอกสารใน FF:

<iframe-elementnode>.contentDocumentดู google "mdn contentDocument" สำหรับ appr สมาชิกเช่น 'textContent' เป็นต้น 'เมื่อหลายปีก่อนและไม่ชอบที่จะคลาน หากยังมีความจำเป็นเร่งด่วนให้เอ่ยถึงสิ่งนี้ว่าฉันจะต้องดำน้ำใน ...



1

document.documentElementใช้

ตอบคำถามเดียวกันที่นี่: https://stackoverflow.com/a/7289396/2164160


คำถามนั้นควรถูกปิดเหมือนสำเนาที่ซ้ำกันซึ่งค่อนข้างเก่า อย่างไรก็ตามส่วนที่น่าสนใจคือการที่คุณต้องการ.outerHTMLและเพื่อให้ได้document.doctypeและคำตอบที่สมบูรณ์ที่สุดคือเปาโล
Dan Dascalescu

1

เพื่อให้ได้สิ่งนอก<html>...</html>, สิ่งสำคัญที่สุดคือการ<!DOCTYPE ...>ประกาศ, คุณสามารถเดินผ่าน document.childNodes, เปลี่ยนเป็นสตริง:

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

ฉันเผยแพร่รหัสนี้เป็นdocument-outerhtmlเมื่อเวลา 23.00 น.


แก้ไขหมายเหตุรหัสด้านบนขึ้นอยู่กับฟังก์ชั่นdoctypeToString; การใช้งานอาจมีดังต่อไปนี้ (โค้ดด้านล่างนี้เผยแพร่เมื่อ npm เป็น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
}


0

ฉันมักจะใช้

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

อาจไม่ใช่วิธีที่ถูกต้อง แต่ฉันสามารถเข้าใจได้เมื่อฉันเห็นมัน


สิ่งนี้ไม่ถูกต้องเพราะจะไม่ส่งคืน<html...>แท็ก
Dan Dascalescu

0

ฉันต้องการ doctype html และควรทำงานได้ดีใน IE11, Edge และ Chrome ฉันใช้โค้ดด้านล่างมันใช้งานได้ดี

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

และในแท็กสมอของคุณใช้เช่นนี้

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

ตัวอย่าง

    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>


0

ฉันใช้outerHTMLสำหรับองค์ประกอบ ( <html>คอนเทนเนอร์หลัก) และXMLSerializerสำหรับสิ่งอื่นรวมถึง<!DOCTYPE>ความคิดเห็นแบบสุ่มนอก<html>คอนเทนเนอร์หรืออะไรก็ได้ที่อาจมี ดูเหมือนว่าช่องว่างที่ไม่ได้รับการเก็บรักษาไว้นอกองค์ประกอบดังนั้นฉันเพิ่มขึ้นบรรทัดใหม่โดยเริ่มต้นด้วย<html>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));


-2

คุณต้องวนซ้ำเอกสารโหนดและรับเนื้อหา outerHTML

ใน VBA ดูเหมือนว่านี้

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

การใช้สิ่งนี้จะช่วยให้คุณสามารถรับองค์ประกอบทั้งหมดของหน้าเว็บรวมถึงโหนด <! DOCTYPE> หากมีอยู่


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.