11486 sujets

JavaScript, DOM et API Web HTML5

Pages :
Bonjour la liste !

Je suis en train de faire un dictionnaire en ligne avec un champ de saisie des premières lettres du mot recherché qui déclenche l'apparition d'une liste de mots correspondants. Vous pouvez visualiser la chose ici. Si on tape bara ou abad (essayez !), pas de problème, mais si on rentre un caractère accentué ou un tilde, la liste n'apparaît pas. Exemple : loagañ ; rendu au ñ, la liste s'efface.

Pour l'instant j'ai un mélange innommable de ISO et de UTF8 ; j'ai donc décidé de tout passer en UTF-8 (fichiers sources, champs de la base de données, déclarations PHP, etc.). En localhost pour l'instant. Ajax ne fonctionne plus du tout, dès que je tape une lettre, j'ai droit à une fenêtre :

Erreur de lecture de la r?ponse : TypeError: Cannot read property 'documentElement' of null (Le ? est d'origine)

Voici le fichier javascript :

var xmlHttp = createXmlHttpRequestObject();
function createXmlHttpRequestObject() 
{
  var xmlHttp;
  try
  {
    xmlHttp = new XMLHttpRequest();
  }
  catch (e)
  {
    try
    {
      xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    catch(e) { }
  }
  if (!xmlHttp)
    alert("Erreur de création de l'objet XMLHttpRequest.");
  else 
    return xmlHttp;
}

function process()
{
  
  if (xmlHttp)
  {
    try
    {
      name = encodeURIComponent(document.getElementById("ger").value); 
      if (name == '') {name = 'x'};
      xmlHttp.open("GET", "testajax.php5?name=" + name, true);
      xmlHttp.onreadystatechange = handleRequestStateChange;
      xmlHttp.send(null);
    }
    catch (e)
    {
      alert("Connexion au serveur impossible :\n" + e.toString());
    }
  }
}

function handleRequestStateChange() 
{
  if (xmlHttp.readyState == 4) 
  {
    if (xmlHttp.status == 200 || xmlHttp.status == 304) 
    {
      try
      {
        handleServerResponse();
      }
      catch(e)
      {
        alert("Erreur de lecture de la réponse : " + e.toString());
      }
    } 
   /* else
    {
      alert("Problème d'obtention des données :\n" + xmlHttp.statusText);
    }
    */ 
  }
}

function handleServerResponse()
{
  var xmlResponse = xmlHttp.responseXML;
  xmlRoot = xmlResponse.documentElement;  
  kinnigArray = xmlRoot.getElementsByTagName("kinnig");
  var html = "";  
  for (var i=0; i<kinnigArray.length; i++)
  {html += '<a onclick="onKlik(this.textContent, 0)">' + kinnigArray.item(i).firstChild.data + '</a>';}
  var xmlResponse = xmlHttp.responseText;
  var myDiv = document.getElementById("goulakaat");
  myDiv.innerHTML = html;
}


et le fichier php concerné :

<?php
header('Content-Type: text/xml ; charset = utf-8');
include ('connect.inc.php');

$dom = new DOMDocument();
$respont = $dom->createElement('respont');
$dom->appendChild($respont);

$name = $_GET['name'];
$kinnigou = mysql_query("SELECT poz FROM ajaks WHERE poz LIKE '".$name."%"."' LIMIT 20");
while ($linenn = mysql_fetch_array($kinnigou))
{
$kinnig = $dom->createElement('kinnig');
$encoded=htmlentities ("$linenn[poz]", ENT_QUOTES, 'ISO-8859-1');
$kinnigText = $dom->createTextNode("$encoded"); 
$kinnig->appendChild($kinnigText);
$respont->appendChild($kinnig);
}

$xmlString = $dom->saveXML();
echo $xmlString;

mysql_close();
?>


J'ai essayé de remplacer ISO par UTF-8 dans cette ligne :
$encoded=htmlentities ("$linenn[poz]", ENT_QUOTES, 'ISO-8859-1');

mais sans succès.

Merci de votre attention,
Kristen
Modifié par kristen (02 Dec 2018 - 08:49)
Modérateur
Bonjour,

A priori, l'erreur indique que xmlResponse est null. Les raisons peuvent être multiples, mais la première à envisager est que la réponse ne soit pas du XML valide.

Il faudrait commencer par faire le test suivant :
1) remplacer var xmlResponse = xmlHttp.responseXML; par var xmlResponse = xmlHttp. responseText; dans la fonction handleServerResponse
2) faire un alert(xmlResponse) juste après pour voir si ça contient quelque chose et à quoi ça ressemble. Après le alert, ça va planter mais c'est normal.

Si ça renvoie quelque chose, alors c'est donc que la réponse existe bien mais n'est pas du XML valide. Sinon, c'est qu'il y a un autre problème côté serveur.

Je note qu'un peu plus loin dans la fonction handleServerResponse, il y a une ligne var xmlResponse = xmlHttp.responseText;. Il faudrait changer le nom de cette variable qui est déjà utilisée plus haut, par exemple en utilisant textResponse au lieu de xmlResponse, puis de changer les lignes qui suivent évidemment pour tenir compte de cette modification.

Amicalement,

PS: et as-tu essayé les modifs de mon post précédent ? ça donne quoi ?
Modifié par parsimonhi (08 Dec 2018 - 14:41)
Merci Parsimonhi, mais j'ai fait les modifs indiquées sans succès (message : xmlRoot not defined). De plus n'oublions que ce code marchait très bien (sauf pour les caractères accentués) avant le changement d'encodage. C'est donc à priori c'est au niveau de l'encodage que ça ne va pas, pas au niveau XML.
Modérateur
Bonjour,

C'est normal que xmlRoot soit undefined si on fait un var xmlResponse = xmlHttp. responseText; (j'ai bien précisé qu'après le alert(), le code allait planter).

La question est : est-ce que ton alert a renvoyé quelque chose ?

Amicalement,
En faisant les modifications que tu indiques, soit ;

function handleServerResponse()
{
  var xmlResponse = xmlHttp.responseText;
  alert (xmlResponse);
  xmlRoot = xmlResponse.documentElement;  
  kinnigArray = xmlRoot.getElementsByTagName("kinnig");
  var html = "";  
  for (var i=0; i<kinnigArray.length; i++)
  {html += '<a onclick="onKlik(this.textContent, 0)">' + kinnigArray.item(i).firstChild.data + '</a>';}
  var myDiv = document.getElementById("goulakaat");
  myDiv.innerHTML = html;
}

je n'ai pas de message d'alerte (le code n'est pas interprété) mais toujours le même message d'erreur que précédemment ; quant à la ligne avant var myDiv :
var xmlResponse = xmlHttp.responseText;

je l'ai supprimée, elle ne sert à rien
Modifié par kristen (03 Dec 2018 - 05:45)
Modérateur
Bonjour,

Remplace la fonction handleRequestStateChange par :

function handleRequestStateChange() 
{
  if (xmlHttp.readyState == 4) 
    if (xmlHttp.status == 200 || xmlHttp.status == 304) 
      alert(xmlHttp.responseText);
}


Et remplace ton fichier php par :

<?php
echo "coucou";
?>


Si ton alert affiche "coucou", alors remet morceau par morceau ce qu'il y a dans le php jusqu'à voir les informations attendues dans l'alert.

Ensuite (et seulement ensuite), tu pourras passer au déboggage du javascript en utilisant le même genre de méthode (en remettant par petit bout le code du javascript).

Si ton alert n'affiche pas "coucou", c'est que le problème est ailleurs (on verra si c'est le cas comment faire pour avancer dans le diagnostic).

Amicalement,
Salut Parsimonhi ( et au passage un grand merci !)

J'ai fait les modifs suggérées et résultat :
1 - le message d'alerte ne s'affiche pas
2 - j'ai toujours la même fenêtre d'erreur qu'auparavant
Modérateur
Bonsoir,

On n'est pas rendu ! Smiley smile

On va devoir tout analyser !

Question : tu fais comment pour tester en local ? tu as quoi comme serveur d'installé, et sur quel genre de machine ?

Amicalement,
Comme tu dis, on ne voit guère le bout du tunnel...

Je suis sur un vieux PC sous Linux Mint, avec un serveur LAMP classique (PHP5 et MariaDB). J'utilise Geany pour écrire et modifier mes fichiers. Après chaque modif je lance localhost/geriadur/index.php5 (le fichier index) ou je rafraîchis l'affichage s'il est déjà lancé avec le bouton en forme de flêche ronde sur Chrome.

J'en arrive d'ailleurs à me demander si ça suffit quand je vois toujours le même message d'erreur après certaines modifs...
Modérateur
kristen a écrit :

Je suis sur un vieux PC sous Linux Mint, avec un serveur LAMP classique (PHP5 et MariaDB). J'utilise Geany pour écrire et modifier mes fichiers. Après chaque modif je lance localhost/geriadur/index.php5 (le fichier index) ou je rafraîchis l'affichage s'il est déjà lancé avec le bouton en forme de flêche ronde sur Chrome.


Bon, ça devrait aller !

kristen a écrit :
J'en arrive d'ailleurs à me demander si ça suffit quand je vois toujours le même message d'erreur après certaines modifs...


Déjà, sous Chrome, en même temps que tu cliques sur le bouton de rafraîchissement, appuie sur la touche Majuscule. Car effectivement, selon les cas, il peut utiliser ce qu'il a en cache au lieu du dernier code modifié.

Si après avoir modifié "handleRequestStateChange" qui devrait simplement afficher "coucou" dans une alerte, c'est en effet bizarre s'il t'affiche une erreur dans le code de "handleServerResponse"(que je suppose correspondre à ce que tu appelles "le même message d'erreur") parce qu'on ne passe plus dans cette fonction du tout en théorie. Etait-ce bien le cas ?

Amicalement,
Nom d'un petit bonhomme ! bouton de rafraîchissement + Maj et j'ai bien mon 'coucou !'... Quand je pense aux heures que j'ai dû perdre à cause de ça...

Bon, du coup, je vais réessayer toutes tes solutions dans l'ordre, mais je devrai attendre ce soir pour ça (esclavage salarial dans la journée..). En tout cas, merci pour la manip, et je ne dois pas être le seul à me faire avoir avec ça.
bon j'ai donc modifié mon code comme tu me le suggérais au début =>

1 - fenêtre d'alerte :
From localhost
<?xml version='1.0'?>
</respont>
Effectivement, c'est peu... L'erreur serait dans le fichier PHP ? Pourtant il fonctionne impec' sur la version en ligne ?!??

2 - suivi du message d'erreur suivant :
From localhost
erreur de lecture de la réponse: TypeError: Cannot read property 'getElementsByTagName' of undefined
Modifié par kristen (04 Dec 2018 - 19:42)
Modérateur
Bonsoir,

L'erreur est soit dans le fichier php soit ailleurs ! (je m'étonne parfois !)

Plus sérieusement, c'est clair que le fichier php ne t'envoie pas ce qu'il faut. Mais l'erreur peut venir de lui, ou de ce qu'on lui fournit.

Donc, on met tout en commentaire dans le fichier php et on avance ligne par ligne en faisant un echo, et on voit ce qu'il y a dans l'alert.

Pourquoi tu mets des guillemets autour de
$linenn[poz]
et
$encoded
?

Pourquoi y-a-t-il un 'ISO-8859-1' qui traine si tout est en utf-8 ?

Amicalement,
Modifié par parsimonhi (04 Dec 2018 - 23:01)
Modérateur
Bonjour,

Le message concernant le "getElementsByTagName" est a priori une conséquence du fait que la réponse envoyée par le php n'est pas conforme. L'objet xmlRoot vaut surement null, et donc toute utilisation ultérieure de cet objet produira une erreur.

Il faut d'abord obtenir une réponse correcte fournie par le php du serveur, avant de s'intéresser aux erreurs javascript qui disparaitront sans doute toutes seules, une fois ce problème de validité de la réponse réglé.

Amicalement,
Modifié par parsimonhi (04 Dec 2018 - 23:13)
Bon en fait je suis désolé de t'avoir égaré hier soir sur une mauvaise piste : le résultat de l'alerte dépend évidemment de ce qu'on tape et celui que j'ai donné devait provenir d'un vidage du champ de saisie. Le code PHP semble fonctionner parfaitement : après avoir tapé les 4 lettres de abad, xmlResponse vaut :
<?xml version="1.0"?><respont><kinnig>abad</kinnig>abadenn<kinnig>abadennad</kinnig><kinnig>abadenner</kinnig><kinnig>abadiezh</kinnig><kinnig>abadorenn</kinnig></respont>


Mais je dis semble car j'ai comparé les résultats en ligne et en localhost :
en remplaçant
var xmlResponse = xmlHttp.responseXML;

par
var xmlResponse = xmlHttp.responseText;

les deux alert me donnent le même résultat.

mais si je rétablis
var xmlResponse = xmlHttp.responseXML;

mon alerte en ligne m'indique que xmlResponse vaut
[object XMLDocument]

et en local
null


Les guillemets ? euh... ça marchait comme ça !
Le ISO-8859-1, c'est un oubli. Je l'ai remplacé par UTF-8 sans plus de succès.
Modifié par kristen (05 Dec 2018 - 07:21)
Modérateur
Bonsoir,

kristen a écrit :
Le code PHP semble fonctionner parfaitement...

On avance ! Smiley smile

kristen a écrit :
...mais si je rétablis
var xmlResponse = xmlHttp.responseXML;

mon alerte en ligne m'indique que xmlResponse vaut
[object XMLDocument]

et en local
null

C'est effectivement bizarre !

Tu vas faire 2 choses dans ton fichier php :

1) remplacer la première ligne de ton fichier php par :
header('Content-Type: application/xml; charset=utf-8');

application/xml semble plus indiqué que text/xml, même si je ne crois pas trop que cela change quelque chose dans ton cas.

2) ajouter juste avant la ligne "echo $xmlString;" :
file_put_contents("testdata.xml", $xmlString);

L'idée est de vérifier que tu as bien ce que tu attends dans le fichier testdata.xml.

Et tu regardes si ça passe au niveau du javascript.

Si ça ne passe toujours pas, tu tentes de remplacer dans la fonction javascript "handleServerResponse" la ligne :
var xmlResponse = xmlHttp.responseXML;

par la ligne :
var xmlResponse = new DOMParser().parseFromString(xmlHttp.responseText,'text/xml');

Ici, l'idée est d'utiliser le responseText, puisque tu dis qu'il semble bon, et de le transformer en objet XML.

Et tu regardes si ça passe au niveau du javascript.

Amicalement,
Modifié par parsimonhi (06 Dec 2018 - 08:20)
Modérateur
Bonjour,
rossi123 a écrit :

oui c vrai .toute utilisation ultérieure de cet objet produira une erreur mais ya une possibilite d'eviter ces erreurs

1) Corriger les erreurs qu'il y a avant
2) Corriger les erreurs qu'il y a avant
3) Corriger les erreurs qu'il y a avant

Sinon, on peut toujours mettre en commentaire les lignes qui font des erreurs par la suite, mais c'est pas ça qui va faire "vraiment" marcher le truc !

On peut aussi inclure des tests dans le code qui en cas d'erreur vont afficher un message dans la page au lieu de faire une erreur produite par le navigateur. Par exemple (au passage, j'ai mis un peu d'ordre dans ton code) :

function handleServerResponse()
{
  var xmlResponse, xmlRoot, kinningArray, html, i, myDiv;
  xmlResponse = xmlHttp.responseXML;
  if (xmlResponse&&xmlResponse.documentElement)
  {
    xmlRoot = xmlResponse.documentElement;  
    kinnigArray = xmlRoot.getElementsByTagName("kinnig");
    html = "";  
    for (i=0; i<kinnigArray.length; i++)
    {
      html += '<a onclick="onKlik(this.textContent, 0)">';
      html += kinnigArray.item(i).firstChild.data + '</a>';
    }
  }
  else
  {
    html = "Erreur ! Le serveur n'a pas envoyé les informations attendues dans un format correct !";
  }
  myDiv = document.getElementById("goulakaat");
  myDiv.innerHTML = html;
}

Amicalement,
Modifié par parsimonhi (08 Dec 2018 - 14:40)
Bon, je suis au bord de la dépression... Bon, disons que j'ai comme le tournis...

Récapitulons. En codant, suivant les conseils avisés de Parsimonhi :

function handleRequestStateChange() 
{
  if (xmlHttp.readyState == 4) 
    if (xmlHttp.status == 200 || xmlHttp.status == 304) 
    alert(xmlHttp.responseText);
}

function handleServerResponse()
{
  var xmlResponse = xmlHttp.responseXML; 
  xmlRoot = xmlResponse.documentElement;  
  kinnigArray = xmlRoot.getElementsByTagName("kinnig");
  var html = "";  
  for (var i=0; i<kinnigArray.length; i++)
  {html += '<a onclick="onKlik(this.textContent, 0)">' + kinnigArray.item(i).firstChild.data + '</a>';}
  var myDiv = document.getElementById("goulakaat");
  myDiv.innerHTML = html;
}


en tapant abad, j'ai le résultat suivant dans l'alerte de la fonction handleRequestStateChange()

<?xml version="1.0"?><respont><kinnig>abad</kinnig>abadenn<kinnig>abadennad</kinnig><kinnig>abadenner</kinnig><kinnig>abadiezh</kinnig><kinnig>abadorenn</kinnig></respont>


ce qui est bien le résultat désiré ! mais pour une raison indéterminée, ce qui me paraît être du XML valide et pourtant est refusé comme tel dans handleServerResponse()...
kristen a écrit :
Bon, je suis au bord de la dépression... Bon, disons que j'ai comme le tournis...

Récapitulons. En codant, suivant les conseils avisés de Parsimonhi :

function handleRequestStateChange() 
{
  if (xmlHttp.readyState == 4) 
    if (xmlHttp.status == 200 || xmlHttp.status == 304) 
    alert(xmlHttp.responseText);
}

function handleServerResponse()
{
  var xmlResponse = xmlHttp.responseXML; 
  xmlRoot = xmlResponse.documentElement;  
  kinnigArray = xmlRoot.getElementsByTagName("kinnig");
  var html = "";  
  for (var i=0; i&lt;kinnigArray.length; i++)
  {html += '&lt;a onclick="onKlik(this.textContent, 0)"&gt;' + kinnigArray.item(i).firstChild.data + '&lt;/a&gt;';}
  var myDiv = document.getElementById("goulakaat");
  myDiv.innerHTML = html;
}


en tapant abad, j'ai le résultat suivant dans l'alerte de la fonction handleRequestStateChange()

<?xml version="1.0"?><respont><kinnig><abad></kinnig><kinnig<abadenn></kinnig><kinnig><abadennad></kinnig><kinnig>abadenner</kinnig><kinnig>abadiezh</kinnig><kinnig><abadorenn></kinnig></respont>


ce qui est bien le résultat désiré ! mais pour une raison indéterminée, ce qui me paraît être du XML valide et pourtant est refusé comme tel dans handleServerResponse()...


J'ajoute - je ne sais pas si ça peut faire avancer le schmilblick - que si dans la même alerte je remplace xmlHttp.responseText par xmlHttp.responseXML j'ai déjà null comme réponse.
Modifié par kristen (08 Dec 2018 - 18:58)
Pages :