如何将整个文档HTML作为字符串?


Answers:


319

MS添加了outerHTMLinnerHTML不久前属性。

根据MDN的说明outerHTMLFirefox 11,Chrome 0.2,Internet Explorer 4.0,Opera 7,Safari 1.3,Android,Firefox Mobile 11,IE Mobile,Opera Mobile和Safari Mobile支持。outerHTMLDOM解析和序列化规范中。

有关适合您的浏览器的兼容性,请参见quirksmode。全部支持innerHTML

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

28
outsideHTML没有获取doctype。
CMCDragonkai 2014年

2
像魅力一样运作!谢谢!有什么方法可以获取链接到文档的所有/所有文件以及js和CSS文件的大小?
www139 2015年

@CMCDragonkai:您可以单独获取doctype并将其添加到标记字符串之前。我知道这并不理想,但可能。
Mike Branski,2015年

76

你可以做

new XMLSerializer().serializeToString(document)

在比IE 9更高的浏览器中

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


5
这是根据日期/时间戳记的第一个 正确答案。页面的某些部分(例如XML声明)将包括在内,浏览器将在使用其他“答案”时操纵代码。这是唯一应该被投票的帖子(三天后在dos上发布)。人们需要注意!
约翰

2
这不是完全正确,因为它serializeToString执行HTML编码。例如,如果您的代码包含定义字体的样式,例如“ Times New Roman”,Times,衬线,则引号将进行html编码。也许这对你们中的某些人并不重要,但对我来说却很重要
Marko

3
@约翰井OP实际询问“整个HTML 的html标签”。而科林·伯内特(Colin Burnett)选择的最佳答案的确做到了这一点。该特定答案(Erik的答案)将包括html标签和doctype。就是说,对我而言,这完全是一颗钻石,这正是我所寻找的!您的评论也有所帮助,因为它使我花了更多时间在这个答案上,因此,谢谢:)
evanrmurphy 17-10-26

2
我认为人们对此应该谨慎,特别是因为它返回的值不是您的浏览器收到的实际html。就我而言,它html为服务器从未实际发送过的标签添加了属性:(
onassar,

1
每个浏览器都支持它。糟糕的浏览器支持如何?
艾里克·艾格纳

44

我相信 document.documentElement.outerHTML应该为您退还。

根据MDN的说明outerHTMLFirefox 11,Chrome 0.2,Internet Explorer 4.0,Opera 7,Safari 1.3,Android,Firefox Mobile 11,IE Mobile,Opera Mobile和Safari Mobile支持。outerHTMLDOM解析和序列化中规范中。

outerHTML属性上的MSDN页面指出IE 5+支持它。Colin的答案链接到W3C quirksmode页面,该页面很好地比较了跨浏览器的兼容性(也适用于其他DOM功能)。


并非所有浏览器都支持此功能。
科林·伯内特

@Colin:是的,很好。从经验来看,我似乎还记得IE 6+和Firefox都支持它,尽管您链接的quirksmode页面显示了其他信息……
Noldorin

Firefox不支持OuterHTML。它是IE专有的。developer.mozilla.org/En/…–
杰西·迪尔

4
有没有办法获取所有内容,包括doctype和html标签?
trusktr 2012年

1
实际上,我是第一位的。:P
Noldorin

40

我尝试了各种答案以查看返回了什么。我正在使用最新版本的Chrome。

建议document.documentElement.innerHTML;返回<head> ... </body>

加比的建议 document.getElementsByTagName('html')[0].innerHTML;也是如此。

建议document.documentElement.outerHTML;返回<html><head> ... </body></html> 除了'doctype'以外,都是其他。

您可以使用检索doctype对象,document.doctype; 这将返回一个对象,而不是字符串,因此,如果您需要提取所有文档类型的详细信息作为字符串,直到并包括HTML5,请在此处进行描述:使用Javascript将HTML的DocType获取为字符串

我只需要HTML5,因此以下内容足以创建整个文档:

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


6
这是最完整的答案,应该接受。截至2016年,浏览器兼容性已完成,不再需要详细提及(如当前接受的答案中所述)。
Dan Dascalescu

10

您也可以这样做:

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

您将不会获得Doctype或html标记,但会得到其他所有内容...



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中使用。(从源文本的非常开头显示非常多的300个字符,主要是doctype-defs。)

但是请注意,FF的常规“另存为”对话框可能不会保存页面的当前状态,而不会保存最初加载的X / h / tml-source-text!(将ss张贴到某些临时文件并重定向到该临时文件,可能会提供可保存的源文本,以及对其进行的更改/编辑。)

尽管FF对“返回”具有良好的恢复性感到惊讶,而对输入类的FIELDS,textarea等,在“保存(另存为...)”中包含状态/值的NICE却令人惊讶,但对contenteditable / designMode中的元素却没有...

如果不是xhtml- resp。xml文件(MIME类型,而不仅仅是文件扩展名!),可以使用document.open/write/close来设置appr。内容保存到源层,这些内容将从FF的“文件/保存”菜单保存在用户的“保存”对话框中。参见:http : //www.w3.org/MarkUp/2004/xhtml-faq#docwrite响应。

https://developer.mozilla.org/zh-CN/docs/Web/API/document.write

与X(ht)ML的问题无关,请尝试使用“ view-source:http:// ...”作为iscript(脚本制作!?)iframe的src-attrib的值,以访问iframe- FF中的文档:

<iframe-elementnode>.contentDocument,请参阅Google“ mdn contentDocument”以获取相关信息。成员,例如“ textContent”。``那是几年前的事,并且不喜欢它爬行。如果仍然有紧急需要,请提一下,我要潜入...




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

我在npm上将此文档发布为document-outerhtml


编辑注意上面的代码取决于一个函数doctypeToString; 它的实现可以如下(下面的代码以doctype-to-string的形式发布在npm上):

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

您必须遍历文档childNodes并获取externalHTML内容。

在VBA中看起来像这样

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

使用它,可以获取网页的所有元素,包括<!DOCTYPE>节点(如果存在)


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.