Ça marche. J'ai juste séparé les blocs de construction pour une meilleure lisibilité.
Consultez l'explication et les commentaires en ligne pour comprendre le fonctionnement de ce système et pourquoi il doit être conçu de cette manière.
Bien sûr, cela ne peut pas être utilisé pour récupérer du contenu inter-domaine, pour cela vous devez soit faire passer les appels par un script ou penser à intégrer quelque chose comme flXHR (Ajax inter-domaines avec Flash)
appel.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 est (jQuery 1.3.2 non compressé) test.html un document XHTML valide
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);
}
}
});
});
});
Dans Opera, le tout fonctionne sans le createXMLDocument
y el beforeSend
fonction.
L'astuce supplémentaire est nécessaire pour Firefox (3.0.11) et IE6 (je ne peux pas tester IE7, IE8, d'autres navigateurs) car ils ont un problème lorsque la balise Content-Type:
renvoyée par le serveur n'indique pas qu'il s'agit de xml. Mon serveur web renvoie Content-Type: text/html; charset=UTF-8
pour test.html.
Dans ces deux navigateurs, jQuery a appelé la fonction error
avec textStatus
en disant parsererror
. Parce que dans la ligne 3706 dans jQuery.js
data = xml ? xhr.responseXML : xhr.responseText;
data
est défini comme nul. Comme dans FF et IE, le xhr.responseXML
est nulle. Cela se produit parce qu'ils ne comprennent pas que les données retournées sont xml (comme le fait Opera). Et seulement xhr.responseText
est défini avec l'ensemble du code xhtml. Comme les données sont nulles, la ligne 3708
if ( xml && data.documentElement.tagName == "parsererror" )
lance une exception qui est rattrapée à la ligne 3584 et le statut est fixé à parsererror
.
Dans FF, je peux résoudre le problème en utilisant la fonction overrideMimeType()
avant d'envoyer la demande.
Mais IE ne prend pas en charge cette fonction sur l'objet XMLHttpRequest, je dois donc générer le document XML moi-même si la fonction de rappel d'erreur est exécutée et que l'erreur est la suivante parsererror
.
exemple pour 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>