Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Ajax] Problème de requête

en utilisant le dynamic script loading

    8 mars 2009 à 11:44:42

    Bonjour,

    J'ai réussi à résoudre le problème, c'était une variable (var classe pour faire passer en argument) qui était mal placé. J'utilise htmlentities avant l'envoi donc les caractères spéciaux (ç, é etc) sont convertirs en entités html (&ccdil; etc). Seulement, ils ne s'affichent pas en tant que ç mais en tant que ç.

    Comment faire ?

    J'utilise un fichier JSon + le dynamic script loading pour récupérer des données pour des listes déroulantes. Le problème : la requête n'est pas renvoyée à chaque fois.

    Je m'explique : Je veux que lorsque la valeur de la liste déroulante change, une autre liste déroulante change (principe des listes liées). Pour cela, j'utilise le Dynamic Script Loading (en suivant ce tutoriel : <lien url="http://www.siteduzero.com/tutoriel-3-4697-dynamic-script-loading.html">http://www.siteduzero.com/tutoriel-3-4697-dynamic-script-loading.html</lien> ) pour aller chercher les données dans la base et les récupérer. 2 possibilités ensuite (et là c'est le problème ^^) :
    - Si aucune données dans la base, la variable retournée est vide -> je ne récupère rien (normal). Je fais une seconde requête derrière, qui retourne quelque chose, ça marche.
    - Si des données sont retournées, j'ai un retour (normal). Si je refais une autre requête qui renvoie quelque chose, ça marche. Mais si je fais une requête qui renvoie une variable vide, ça ne marche pas, les données restent les même (et j'ai le même retour qu'avant, et pas du vide).

    Mon script :
    Page PHP pour générer le jSon (c'est essentiellement des requêtes à la base de données + json_encode pour convertir le retour en json) :
    <?php
    	header("Content-type: text/javascript; charset=UTF-8");
    	require('init.php');
    	
    	if(!empty($_GET['classe']))
    	{
    		$classe = intval($_GET['classe']);
    		
    		$retour = mysql_query('SELECT id, nom FROM matieres WHERE classe_id='.$classe);
    		if(mysql_num_rows($retour) != 0 && !mysql_error())
    		{
    			$var = array();
    			while($donnees = mysql_fetch_array($retour))
    			{
    				$var[] = array(intval($donnees["id"]), securiser::html($donnees["nom"]));
    			}
    			echo 'var oJson = '.json_encode($var).';';
    		}
    		else
    		{
    			echo 'var oJson;';
    		}
    	}
    	else
    	{
    		$retour_matiere = mysql_query('SELECT id, classe_id, nom FROM matieres ORDER BY id DESC');
    		if(mysql_num_rows($retour_matiere) != 0 && !mysql_error())
    		{
    			$var = array();
    			while($donnees_matiere = mysql_fetch_array($retour_matiere))
    			{
    				$var[] = array(intval($donnees_matiere['id']),'['.$classes[$donnees_matiere['classe_id']][1].'] '.securiser::html($donnees_matiere['nom']));
    			}
    			echo 'var oJson = '.json_encode($var).';';
    		}
    		else
    		{
    			echo 'var oJson;';
    		}
    	}
    	echo 'callback(oJson);';
    ?>
    


    Page js (script inclue sur la page du formulaire) :
    function sendDSL(sUrl, oParams) //Fonction du tuto pour envoyer une requete DSL
    {
    	for(sName in oParams) 
    	{
    		if(sUrl.indexOf("?") != -1) 
    		{
    			sUrl += "&";
    		} 
    		else 
    		{
    			sUrl += "?";
    		}
    		sUrl += encodeURIComponent(sName) + "=" + encodeURIComponent(oParams[sName]);
    	}
    
    	var oScript = document.createElement("script");
    	oScript.src = sUrl;
    	oScript.type = "text/javascript";
    	document.body.appendChild(oScript);
    }
    
    function callback(oJson) //Fonction de callback du tuto, juste pour vérifier le retour
    {
    	var tree = "";
    
    	for(sItem in oJson) 
    	{ 
    		tree += sItem + "\n";
    		var nbItems = oJson[sItem].length;
    		for(var i=0;i<nbItems;i++) 
    		{
    			tree += "\t" + oJson[sItem][i] + "\n";
    		}
    	}
    
    	alert(tree);
    }
    
    
    function matieres() //Fonction principale, appelée au chargement de la fenêtre
    {
    	var liste_classe = document.getElementById('classe'); //Element "liste" = select sur lequel je vérifie le changement
    	var classe = liste_classe.options[liste_classe.selectedIndex].value; //Valeur sélectionnée
    	
    	liste_classe.onchange = function() //En cas de changement
    	{		
    		var matiere = document.getElementById('matiere'); //La liste à modifier
    	
    		//Ici, suppression des éléments de la liste, pas important dans le problème
    		var a_delete = matiere.getElementsByTagName('option');
    		var nbre_elements = a_delete.length;
    
    		for(var i = a_delete.length - 1; i >= 0; i--)
    		{
    			matiere.removeChild(a_delete[i]);
    		}
    		
    		var chargement = document.createElement('option'); //J'ajoute un enfant contenant le texte Chargement -> idem
    		matiere.appendChild(chargement);			
    		matiere.getElementsByTagName('option')[0].setAttribute('value', '');
    		
    		matiere.getElementsByTagName('option')[0].appendChild(document.createTextNode('Chargement ...'));
    
    		var oParams = {"classe": classe };  //Les paramètres à envoyer + requete DSL
    
    		
    		/* var nodes   = xhr.responseXML.getElementsByTagName("item");
    		var option, inner;
    		
    		matiere.innerHTML = "";
    		for(var i = 0, c = nodes.length; i < c; i++) 
    		{
    			option = document.createElement("option");
    			inner  = document.createTextNode(nodes[i].getAttribute("name"));
    			option.value = nodes[i].getAttribute("id");
    			
    			option.appendChild(inner);
    			matiere.appendChild(option);
    		}*/
    	};
    }
    
    if(document.getElementById && document.createTextNode) //Ajout de la fonction matieres au chargement de la fenêtre
    {
    	var oldonload = window.onload;
    	if(typeof window.onload != 'function')
    	{
    		window.onload = matieres();
    	}
    	else
    	{
    		window.onload = function()
    		{
    			oldonload();
    			matieres();
    		}
    	}
    }
    


    Merci
    • Partager sur Facebook
    • Partager sur Twitter
      8 mars 2009 à 16:27:05

      C'est parce que c'est du text/javascript or &ccedil; est un caractère html qui n'existe que dans le type text/html...
      • Partager sur Facebook
      • Partager sur Twitter
        8 mars 2009 à 17:27:40

        Ok, dans ce cas comment puis-je faire ?

        Je viens de penser à quelque chose : Comme je créé mes éléments en JS + DOM, ai-je réellement besoin d'utiliser htmlentities, y a t il des failles XSS ? car les données de la base sont mises comme texte et ne sont pas interprétées ...

        Merci
        • Partager sur Facebook
        • Partager sur Twitter
          8 mars 2009 à 18:21:12

          Pas besoin d'htmlentities non pour le Javascript mais il faut prendre un encodage qui affiche correctement les accents.
          • Partager sur Facebook
          • Partager sur Twitter
            8 mars 2009 à 19:37:13

            Donc :
            1 - Faut-il que je protège mes variables que je transmet en JS et que j'affiche ? C'est à dire, seront-elles interprétées (faille XSS) ou considérées comme du texte (aucun problème) ?
            2 - S'il faut protéger mes variables, comment le faire tout en affichant les accents ?

            Merci

            P.S. : Au niveau de l'encodage, tout mon site est en UTF-8, aucun problème pour ça.
            • Partager sur Facebook
            • Partager sur Twitter
              8 mars 2009 à 19:48:13

              Un simple addslashes pour éviter les les ' et " qui ferment les chaînes mais sinon, pas de risque, c'est du texte. A moins d'utiliser innerHTML au quel cas htmlentities fonctionne.
              • Partager sur Facebook
              • Partager sur Twitter
                9 mars 2009 à 18:14:37

                Ok, donc j'ai 2 solutions :
                - Utiliser juste addslashes pour éviter de fermer des chaines, y a t il un risque de sécurité ?
                - Utiliser html_special_chars à la place, qui ne me convertira pas tous les accents etc

                Selon vous, la première est largement suffisante pour éviter des attaques ?

                Merci
                • Partager sur Facebook
                • Partager sur Twitter
                  13 mars 2009 à 17:54:56

                  Il n'y a pas d'"attaques" possible du tout sur l'ajax, ce ne sont des données de l'utilisateur que tu renvoies à l'utilisateur. Conserver sous forme de chaîne dans du javascript, ce sera toujours du texte.
                  • Partager sur Facebook
                  • Partager sur Twitter

                  [Ajax] Problème de requête

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown