在ajax HTML响应中查找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'); });
问题是,当我改变body
我什么也得不到(没有错误,只有没有HTML)。 我假设身体是一个像’a’的标签? 我究竟做错了什么?
所以这对我有用:
mas = $(data).find('a');
但这不是:
mas = $(data).find('body');
通过jQuery对象解析返回的HTML(即$(data)
)以获取body
标签注定要失败,我担心。
原因是返回的data
是一个string
(尝试console.log(typeof(data))
)。 现在,根据jQuery文档 ,当从包含复杂HTML标记的字符串创建jQuery对象时,诸如body
类的标记可能会被剥离。 这是因为为了创建对象,HTML标记实际上插入到DOM中,这不允许这样的附加标记。
文件中的相关引用:
如果将字符串作为参数传递给$(),jQuery将检查字符串以查看它是否看起来像HTML。
[…]如果HTML比没有属性的单个标签更复杂,就像在上面的例子中那样,元素的实际创建由浏览器的innerHTML机制处理。 在大多数情况下,jQuery会创建一个新元素,并将元素的innerHTML属性设置为传入的HTML片段。当参数有一个标记(带有可选的结束标记或快速关闭)时 – $(““)或$(”“),$(” a>“)或$(”“) – jQuery使用本机JavaScript createElement()函数创建元素。
传递复杂的HTML时,某些浏览器可能无法生成完全复制所提供的HTML源的DOM。 如上所述,jQuery使用浏览器的.innerHTML属性来解析传递的HTML并将其插入到当前文档中。在此过程中,某些浏览器会过滤掉某些元素,例如,
或元素结果,插入的元素可能无法代表传递的原始字符串。
我最终得到了这个简单的解决方案:
var body = data.substring(data.indexOf("")+6,data.indexOf("")); $('body').html(body);
也适用于头部或任何其他标签 。
(使用xml解析的解决方案会更好但是如果XML响应无效,则必须执行一些“字符串解析”。)
我做了一点实验,并确定了原因,所以等待我真正感兴趣的答案,这是一个帮助理解问题的黑客
$.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()) })
编辑:进一步的实验
看起来有可能将内容加载到iframe中,然后您可以通过某个dom对象层次结构访问帧内容…
// get a page using AJAX $.get('/',function(d){ // create a temporary `iframe`, make it hidden, and attach to the DOM var frame = $('').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() }) })
编辑:更多研究
似乎contentDocument是获取iFrame的window.document
元素的标准兼容方式,但当然IE并不真正关心标准,所以这是如何获取对iFrame的window.document.body
的引用。跨平台方式的对象……
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]
请参阅: iframe的contentDocument
我想出了很棒的事情(我想!)
得到你的HTML作为字符串?
var results = //probably an ajax response
这是一个jquery对象,它的工作方式与当前附加到DOM的元素完全相同:
var superConvenient = $($.parseXML(response)).children('html');
什么都不会从superConvenient
剥离出来! 你可以做一些像superConvenient.find('body')
甚至是
superConvenient.find('head > script');
superConvenient
工作原理与每个人习惯的jquery元素完全相同!
注意
在这种情况下,字符串results
需要是有效的XML,因为它被提供给JQuery的parseXML
方法。 HTML响应的一个共同特征可能是标记,这会使文档在这种意义上无效。 在使用此方法之前,可能需要剥离
标记! 还要注意
,标签没有关闭标签,例如:
- content...
- content...
- content...
…以及浏览器将宽大地解释HTML的任何其他function,但会破坏XML解析器。