[AJAX] Reutilisation d'objet XMLHttpRequest lors d'une annulation (abort)
Bonjour,
J'ai un probleme de comportement entre IE6 et FF1.5 lorsque je tente de reutiliser une requete Ajax precedement annulee.
Voici le code source :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ah>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>AJAX ABORT</title>
<script>
// Objet XMLHttpRequest global re-utilise pour chaque requete serveur
var XhrObj = null;
/*
* Fonction de demarrage d'une requete
*/
function startRequest()
{
// creation de l'objet global XMLHttpRequest
if (XhrObj == null)
{
if(typeof(XMLHttpRequest) != 'undefined')
{
// Mozilla
XhrObj = new XMLHttpRequest();
}
else
{
// Noms des activeX des differentes versions d'IE
var axO = ['Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.4.0', 'Msxml2.XMLHTTP.3.0', 'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP'], i;
for(i = 0; i < axO.length; i++)
{
try
{
XhrObj = new ActiveXObject(axO);
break;
}
catch(e)
{
}
}
}
}
XhrObj.open("POST", '/MySiteLocal/AjaxServlet', true);
XhrObj.onreadystatechange = test;
var data = 'ajaxAbort=true';
XhrObj.setRequestHeader('Content-Length', data.length);
XhrObj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
XhrObj.send(data);
}
/*
* Fonction callback onreadystatechange
*/
function test()
{
if (XhrObj.readyState != 4)
return;
if (abort)
{
abort = false;
return;
}
if ((XhrObj.status <= 200) && (XhrObj.status < 300))
alert('Requete OK');
else
alert('Requete NON OK');
}
var EMPTY_FCT = function () {}
var abort = false;
/*
* Fonction d'annulation d'une requete AJAX
* restart : indique s'il faut relancer une requete dans la foulee
*/
function abortRequest1(restart)
{
abort = true;
XhrObj.abort();
XhrObj.onreadystatechange = EMPTY_FCT;
if (restart)
startRequest();
}
/*
* Fonction d'annulation d'une requete AJAX
* restart : indique s'il faut relancer une requete dans la foulee
*/
function abortRequest2(restart)
{
abort = true;
XhrObj.abort();
XhrObj.onreadystatechange = EMPTY_FCT;
if (restart)
setTimeout ('startRequest(false)', 50);
}
</script>
</head>
<body>
<input type='button' value='Demarrer Requete' onclick='startRequest();'/>
<input type='button' value='Annuler Requete' onclick='abortRequest1(false);'/>
<input type='button' value='Annuler Requete et redemarrer version 1' onclick='abortRequest1(true);'/>
<input type='button' value='Annuler Requete et redemarrer version 2' onclick='abortRequest2(true);'/>
</body>
</html> |
Explication :
1) Je clic sur le bouton 'Demarrer Requete' puis j'annule la requete en cliquant sur le bouton 'Annuler Requete'. Si je re-clic sur le bouton 'Demarrer Requete' pas de probleme (la requete s'execute normalement).
2) Je fait la meme chose (demarrage d'une requete puis annulation puis re-demarrage de la meme requete) mais en utilisant une fonction qui fait le re-demarrage dans la foulee de l'annulation :
Je clic sur le bouton 'Demarrer Requete' puis j'annule la requete et la re-demarre en cliquant sur le bouton 'Annuler Requete et redemarrer version 1'.
Sous IE, l'execution se passe normalement.
Sous FF, j'ai l'exception :
[Exception... "Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIXMLHttpRequest.status]" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)" location: "JS frame :: http://localhost:8080/MySiteLocal/html/ajaxAbort2.html :: test :: line 67" data: no]
lorsque je tente de lire l'attribut status de mon objet XhrObj (fonction test)
3) Si par contre je fait la meme chose mais en retardant le re-demarrage de ma requete de 50 ms, alors l'execution se passe normalement sous FF :
Je clic sur le bouton 'Demarrer Requete' puis j'annule la requete et la re-demarre en cliquant sur le bouton 'Annuler Requete et redemarrer version 2'.
Questions :
1) Y-a t-il une solution pour annuler une requete et la re-utiliser dans la foulee sans passer par le setTimeout (abortRequest2) ?
2) S'agit-il d'une erreur d'initialisation de la requete (startRequest) ou d'un bug FF ?
Merci pour votre attention et vos reponses.