在ajax HTML响应中查找body标签

You*_*uss 21 javascript ajax jquery document-body

我正在进行ajax调用以获取内容并附加此内容,如下所示:

$(function(){
    var site = $('input').val();
    $.get('file.php', { site:site }, function(data){
        mas = $(data).find('a');
        mas.map(function(elem, index) {
            divs = $(this).html();
            $('#result').append('' + divs + '');
        })
    }, 'html');
});
Run Code Online (Sandbox Code Playgroud)

问题是,当我改变时a,body我什么也得不到(没有错误,只是没有HTML).我假设身体是一个像'a'的标签?我究竟做错了什么?

这对我有用:

 mas = $(data).find('a');
Run Code Online (Sandbox Code Playgroud)

但这不是:

 mas = $(data).find('body');
Run Code Online (Sandbox Code Playgroud)

Yus*_*sh0 11

我最终得到了这个简单的解决方案:

var body = data.substring(data.indexOf("<body>")+6,data.indexOf("</body>"));
$('body').html(body);
Run Code Online (Sandbox Code Playgroud)

也适用于头部或任何其他标签.

(使用xml解析的解决方案会更好但是如果XML响应无效,则必须执行一些"字符串解析".)


Boa*_*oaz 10

通过jQuery对象(即$(data))来解析返回的HTML 以获取body标记注定要失败,我担心.

原因是返回的datastring(尝试console.log(typeof(data))).现在,根据jQuery文档,当从包含复杂HTML标记的字符串创建jQuery对象时,像这样的标记body很可能被剥离.发生这种情况是因为为了创建对象,HTML标记实际上插入到DOM中,这不允许这样的附加标记.

文件中的相关引用:

如果将字符串作为参数传递给$(),jQuery将检查字符串以查看它是否看起来像HTML.

[...]如果HTML比没有属性的单个标签更复杂,就像在上面的例子中那样,元素的实际创建由浏览器的innerHTML机制处理.在大多数情况下,jQuery创建一个新元素并将元素的innerHTML属性设置为传入的HTML片段.当参数具有单个标记(带有可选的结束标记或快速关闭)时 - $("<img/>")或$("<img>"),$("<a> </ a>")或$("<a>") - jQuery使用本机JavaScript createElement()函数创建元素.

传递复杂的HTML时,某些浏览器可能无法生成完全复制所提供的HTML源的DOM.如上所述,jQuery使用浏览器的.innerHTML属性来解析传递的HTML并将其插入到当前文档中.在此过程中,某些浏览器会过滤掉某些元素,例如<html>,<title>或<head>元素结果,插入的元素可能无法代表传递的原始字符串.


Bil*_*oon 6

我尝试了一点,并确定了原因,所以等待我真正感兴趣的答案,这是一个帮助理解问题的黑客

$.get('/',function(d){
    // replace the `HTML` tags with `NOTHTML` tags
    // and the `BODY` tags with `NOTBODY` tags
    d = d.replace(/(<\/?)html( .+?)?>/gi,'$1NOTHTML$2>',d)
    d = d.replace(/(<\/?)body( .+?)?>/gi,'$1NOTBODY$2>',d)
    // select the `notbody` tag and log for testing
    console.log($(d).find('notbody').html())
})
Run Code Online (Sandbox Code Playgroud)

编辑:进一步的实验

似乎可以将内容加载到iframe中,然后您可以通过某个dom对象层次结构访问框架内容...

// get a page using AJAX
$.get('/',function(d){

    // create a temporary `iframe`, make it hidden, and attach to the DOM
    var frame = $('<iframe id="frame" src="/" style="display: none;"></iframe>').appendTo('body')

    // check that the frame has loaded content
    $(frame).load(function(){

        // grab the HTML from the body, using the raw DOM node (frame[0])
        // and more specifically, it's `contentDocument` property
        var html = $('body',frame[0].contentDocument).html()

        // check the HTML
        console.log(html)

        // remove the temporary iframe
        $("#frame").remove()

    })
})
Run Code Online (Sandbox Code Playgroud)

编辑:更多研究

似乎contentDocument是获取window.documentiFrame元素的标准兼容方式,但当然IE并不真正关心标准,因此这是如何以window.document.body跨平台方式获取对iFrame 对象的引用. .

var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
var iframeBody = iframeDoc.body;
// or for extra caution, to support even more obsolete browsers
// var iframeBody = iframeDoc.getElementsByTagName("body")[0]
Run Code Online (Sandbox Code Playgroud)

请参阅:iframe的contentDocument


Ger*_*ica 5

我想出了很棒的东西(我想!)

得到你的HTML作为字符串?

var results = //probably an ajax response
Run Code Online (Sandbox Code Playgroud)

这是一个jquery对象,它的工作方式与当前附加到DOM的元素完全相同:

var superConvenient = $($.parseXML(response)).children('html');
Run Code Online (Sandbox Code Playgroud)

什么都不会被剥夺superConvenient!你可以做类似的superConvenient.find('body')甚至是

superConvenient.find('head > script');
Run Code Online (Sandbox Code Playgroud)

superConvenient 完全像每个人都习惯的jquery元素!

注意

在这种情况下,字符串results需要是有效的XML,因为它被提供给JQuery的parseXML方法.HTML响应的一个共同特征可能是<!DOCTYPE>标记,这会使文档在这种意义上无效.<!DOCTYPE>在使用这种方法之前,可能需要剥离标签!还要注意功能<!--[if IE 8]>...<![endif]-->,例如没有关闭标签的标签,例如:

<ul>
    <li>content...
    <li>content...
    <li>content...
</ul>
Run Code Online (Sandbox Code Playgroud)

...以及HTML的任何其他功能将被浏览器宽大地解释,但会破坏XML解析器.

  • 我使用相同的代码,但得到一个错误未捕获错误:无效的XML:<head> (2认同)