用jQueryparsing远程内容的最佳做法是什么?

在jQuery ajax调用来检索整个XHTML文档之后,从结果string中select特定元素的最佳方法是什么? 也许有一个库或插件可以解决这个问题?

jQuery只能select存在于string中的XHTML元素,如果它们通常在W3C规范的div中被允许的话; 因此,我很好奇select诸如<title><script><style>

根据jQuery文档:

http://docs.jquery.com/Core/jQuery#htmlownerDocument

HTMLstring不能包含div内无效的元素,例如html,head,body或title元素。

因此,既然我们已经确定jQuery不提供这样做的方法,那么我将如何select这些元素呢? 举个例子,如果你能告诉我如何select远程页面的标题,这将是完美的!

谢谢,皮特

而不是黑客jQuery做到这一点,我build议你退出jQuery一分钟,并使用原始的XML DOM方法。 使用XML Dom方法你可以做到这一点:

  window.onload = function(){ $.ajax({ type: 'GET', url: 'text.html', dataType: 'html', success: function(data) { //cross platform xml object creation from w3schools try //Internet Explorer { xmlDoc=new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async="false"; xmlDoc.loadXML(data); } catch(e) { try // Firefox, Mozilla, Opera, etc. { parser=new DOMParser(); xmlDoc=parser.parseFromString(data,"text/xml"); } catch(e) { alert(e.message); return; } } alert(xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue); } }); } 

不要搞乱iframes等

只是一个想法 – 在FF / Safaritesting – 似乎工作,如果你创build一个iframe临时存储文档。 当然,如果你这样做,只需要使用iframe的src属性来加载文档,并在其“onload”中做任何你想做的事情可能会更聪明。

  $(function() { $.ajax({ type: 'GET', url: 'result.html', dataType: 'html', success: function(data) { var $frame = $("<iframe src='about:blank'/>").hide(); $frame.appendTo('body'); var doc = $frame.get(0).contentWindow.document; doc.write(data); var $title = $("title", doc); alert('Title: '+$title.text() ); $frame.remove(); } }); }); 

我不得不附加iframe到身体得到它有一个.contentWindow。

从这个答案启发,但推迟:

 function fetchDoc(url) { var dfd; dfd = $.Deferred(); $.get(url).done(function (data, textStatus, jqXHR) { var $iframe = $('<iframe style="display:none;"/>').appendTo('body'); var $doc = $iframe.contents(); var doc = $doc[0]; $iframe.load(function() { dfd.resolveWith(doc, [data, textStatus, jqXHR]); return $iframe.remove(); }); doc.open(); doc.write(data); return doc.close(); }).fail(dfd.reject); return dfd.promise(); }; 

和它一起吸烟:

 fetchDoc('/foo.html').done(function (data, textStatus, jqXHR) { alert($('title', this).text()); }); 

LIVE DEMO (点击“运行”)

如何快速标记重命名?

 $.ajax({ type : "GET", url : 'results.html', dataType : "html", success: function(data) { data = data.replace(/html/g, "xhtmlx"); data = data.replace(/head/g, "xheadx"); data = data.replace(/title/g, "xtitlex"); data = data.replace(/body/g, "xbodyx"); alert($(data).find("xtitlex").text()); } }); 

这工作。 为了更好的可读性,我只是把构build块分开。

检查解释和内联的评论,以掌握这个工作,为什么必须这样做。

当然,这不能用于检索跨域内容,因为您必须通过您的脚本来代理调用,或者考虑像flXHR(跨域Ajax与Flash)

call.html

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>asd</title> <script src="jquery.js" type="text/javascript"></script> <script src="xmlDoc.js" type="text/javascript"></script> <script src="output.js" type="text/javascript"></script> <script src="ready.js" type="text/javascript"></script> </head> <body> <div> <input type="button" id="getit" value="GetIt" /> </div> </body> </html> 

jquery.js是(jQuery 1.3.2 uncompressed) test.html一个有效的XHTML文档

xmlDoc.js

 // helper function to create XMLDocument out of a string jQuery.createXMLDocument = function( s ) { var xmlDoc; // is it a IE? if ( window.ActiveXObject ) { xmlDoc = new ActiveXObject('Microsoft.XMLDOM'); xmlDoc.async = "false"; // prevent erros as IE tries to resolve the URL in the DOCTYPE xmlDoc.resolveExternals = false; xmlDoc.validateOnParse = false; xmlDoc.loadXML(s); } else { // non IE. give me DOMParser // theoretically this else branch should never be called // but just in case. xmlDoc = ( new DOMParser() ).parseFromString( s, "text/xml" ); } return xmlDoc; }; 

output.js

 // Output the title of the loaded page // And get the script-tags and output either the // src attribute or code function headerData(data) { // give me the head element var x = jQuery("head", data).eq(0); // output title alert(jQuery("title", x).eq(0).text()); // for all scripttags which include a file out put src jQuery("script[src]", x).each(function(index) { alert((index+1)+" "+jQuery.attr(this, 'src')); }); // for all scripttags which are inline javascript output code jQuery("script:not([src])", x).each(function(index) { alert(this.text); }); } 

ready.js

 $(document).ready(function() { $('#getit').click(function() { $.ajax({ type : "GET", url : 'test.html', dataType : "xml", // overwrite content-type returned by server to ensure // the response getst treated as xml beforeSend: function(xhr) { // IE doesn't support this so check before using if (xhr.overrideMimeType) { xhr.overrideMimeType('text/xml'); } }, success: function(data) { headerData(data); }, error : function(xhr, textStatus, errorThrown) { // if loading the response as xml failed try it manually // in theory this should only happen for IE // maybe some if (textStatus == 'parsererror') { var xmlDoc = jQuery.createXMLDocument(xhr.responseText); headerData(xmlDoc); } else { alert("Failed: " + textStatus + " " + errorThrown); } } }); }); }); 

在Opera中,整个事情没有createXMLDocumentbeforeSend函数。

Firefox(3.0.11)和IE6(不能testingIE7,IE8和其他浏览器)需要额外的技巧,因为当服务器返回的Content-Type:没有指出它是xml时,它们有问题。 我的networking服务器返回Content-Type: text/html; charset=UTF-8 Content-Type: text/html; charset=UTF-8 for test.html. 在这两个浏览器jQuery调用errorcallback与textStatusparsererror 。 因为在jQuery.js的第3706行

 data = xml ? xhr.responseXML : xhr.responseText; 

data被设置为空。 在FF和IE中, xhr.responseXML为空。 发生这种情况是因为他们不知道返回的数据是xml(就像Opera一样)。 只有xhr.responseText设置了整个xhtml代码。 数据为空行3708

 if ( xml && data.documentElement.tagName == "parsererror" ) 

抛出一个3584行捕获的exception,状态设置为parsererror

在FF中,我可以通过在发送请求之前使用overrideMimeType()函数来解决问题。

但是IE不支持XMLHttpRequest对象上的这个函数,所以如果运行错误callback并且错误是parsererror ,我必须自己生成XMLDocument。

test.html的例子

 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>Plugins | jQuery Plugins</title> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript">var imagePath = '/content/img/so/';</script> </head> <body> </body> </html> 

从我的另一个答案( 简单的jQuery AJAX示例没有在返回的HTML中find元素 )无耻地复制和改编,这将获取远程页面的HTML,然后parseHTML函数创build一个临时的div元素,并放在里面,贯穿它,并返回请求的元素。 jQuery然后警告里面的文本()。

 $(document).ready(function(){ $('input').click(function(){ $.ajax({ type : "POST", url : 'ajaxtestload.html', dataType : "html", success: function(data) { alert( data ); // shows whole dom var gotcha = parseHTML(data, 'TITLE'); // nodeName property returns uppercase if (gotcha) { alert($(gotcha).html()); // returns null }else{ alert('Tag not found.'); } }, error : function() { alert("Sorry, The requested property could not be found."); } }); }); }); function parseHTML(html, tagName) { var root = document.createElement("div"); root.innerHTML = html; // Get all child nodes of root div var allChilds = root.childNodes; for (var i = 0; i < allChilds.length; i++) { if (allChilds[i].nodeName == tagName) { return allChilds[i]; } } return false; } 

要得到几个项目或脚本标签列表,说,我认为你必须改善parseHTMLfunction,但嘿 – 概念validation:-)

如果你想find具体命名的字段(即表单中的input)的值,可以为你find它们:

 var fields = ["firstname","surname", ...."foo"]; function findFields(form, fields) { var form = $(form); fields.forEach(function(field) { var val = form.find("[name="+field+"]").val(); .... 

怎么样: 从string加载XML

 $.get('yourpage.html',function(data){ var content = $('<div/>').append(data).find('#yourelement').html(); }); 

你也可以简单地暂时包装一个div。 你甚至不需要把它添加到DOM。

将XMLstringparsing成XML DOM ,我可以直接使用jQuery (可以通过向jQUeryselect器提供一个上下文来实现,比如$(':title', xdoc.rootElement)或者使用XPath在火狐浏览器中工作,有IE浏览器的图书馆,但我没有与他们取得好成绩)。