11540 sujets

JavaScript, DOM et API Web HTML5

Pages :
Bonjour à tous,

Bon cette fois-ci, c’est un vrai florilège de questions sur le comportement AJAX + PHP + JSON + Accès à une base de données

Je ne sais pas enfin de compte si le traitement d’erreur provient :
1-Du type d’erreur suite à l'accès à une base de données
2-De l’existence d’un caractère spécial dans la chaine JSON avec un ô


Ca parait un peu obscure comme àa mais après lecture de la suite, je suis certain que cela va s'éclaircir!

Bien, commençons par le début, le code

Sur l’événement Onclick d’un bouton d’une form HTML, la fonction JavaScript est lancée:
 function logIn()
{   alert("connexion debut");
    try
    {      var serialData = $( "#frmLogIn" ).serialize();
            $.ajax
            (   {   type: "POST",
                    url: "logInTest.php",
                    data: serialData,
                    dataType: "json",
                    success: function(dataSQL, statut)
                    {   alert("msg" + dataSQL["msg"]);
                    },
                    error: function(dataSQL, statut)
                    {   alert("msg " + dataSQL["msg"]);
                    }
                }
            );
    }
    catch (e)
    {   alert ('An error has occurred: '+ e.message);
    }
} 


Le code de la page PHP est:
 <?php
session_start();

error_reporting(E_ALL);
ini_set( 'display_errors','1');

require "dbConnect.php";

header('Content-Type: application/json; charset=utf-8');
$user = urldecode($_POST["txtUser"]);
$pwd = urldecode($_POST["txtpwd"]);

$sqlSelect = " SELECT * FROM participant WHERE USER = '$user' AND PWD = '$pwd'";

try
{   $dbConnect = dbConnection();
    $dataSet = $dbConnect->query($sqlSelect);
    $rowsArray = $dataSet->fetchAll();
    $returnData =  json_encode($rowsArray);    
    if (count($rowsArray)>0)
    {   $_SESSION["userID"] = $rowsArray[0]["IDPARTICIPANT"];  
    }
 
}catch (PDOException $e)
{  $stringVar = utf8_encode($e->getMessage());
   $msg =  array("msg" =>  $stringVar);
   $returnData = preg_replace("/\\\\u([a-f0-9]{4})/e", "iconv('UCS-4LE','UTF-8',pack('V', hexdec('U$1')))", json_encode($msg));
   //die();
}

$dbConnect = null;// Fermeture connexion
echo $returnData;
?> 


L’auteur de la fonction preg_replace("/\\\\u([a-f0-9]{4})/e", "iconv('UCS-4LE','UTF-8',pack('V', hexdec('U$1')))", json_encode($Varaible)); : est à cette adresse [URL]http://benjion.wordpress.com/2013/01/03/php-json_encode-et-probleme-avec-les-accents/#comment-489[/URL]


Et le code de la page de connexion php est :
 <?php
function dbConnection()
{   $options = array( 
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8",
    );

    $host = "localhost1";
    $dbname = "questionnaire1";    
    $dsn = "mysql:host=". $host.";dbname=".$dbname; //$dsn = 'mysql:dbname=xoccaslite;host=127.0.0.1';
    $username = 'root';
    $password = '';
        $dbConnect = new PDO($dsn, $username, $password, $options);

    return $dbConnect;
 }
?> 



Bon coté codage a priori pas de problème

Maintenant ça se corse quand

1- l’erreur sur la base de données est sur la connexion - $dbConnect = new PDO($dsn, $username, $password, $options) -- ou sur l’exécution de la la requête
2-]Sur l’encode JSON


Reprenons gentiment l’un après l’autre les problèmes :

l’erreur sur la base de données est sur la connexion - $dbConnect = new PDO($dsn, $username, $password, $options) -- ou sur l’exécution de la la requête
]

Si c’est une erreur sur $dbConnect = new PDO($dsn, $username, $password, $options) en raison d’un host = localhost1 inexistant alors c’est bien trappé comme erreur et après traitement , ce message est renvoyé à AJAX sous forme d’une chaine au format JSON = "{"msg":"SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Hôte inconnu. "}"
upload/52547-php1.jpg

Par contre l’erreur est traitée dans AJAX
error: function(dataSQL, statut)
                    {   alert("msg " + dataSQL["msg"]);
                    } 


1-ma variable dataSQL d’AJAX qui récupère les données envoyées par le server se transforme en Objet avec toute sa description cf ci-dessous
2-alert("msg " + dataSQL["msg"] renvoie msg undefined

upload/52547-error1.jpg

Alors que si c’est un problème de nom de table par exemple c’est traité coté AJAX par
success: function(dataSQL, statut)
                    {   alert("msg " + dataSQL["msg"]);
                    } 


Et [QUOTE]alert("msg " + dataSQL["msg"] renvoie bien msg SQLSTATE[HY000] [1049] Unknown database 'questionnaire1'. Cf. ci-dessous[/QUOTE]
upload/52547-error2.jpg

Je m’arrache les cheveux sur ce problème même si maintenant je n’ai plus à la place de ô le signe cabalistique \fffutd.

Merci à tous pour vos solutions
Modifié par informer (17 Jun 2014 - 17:34)
Bonjour Parsimonhi

Merci par avance pour ton aide! Smiley biggrin

Questions:
1- Pourquoi si c'est une erreur sur le host de la chaine de connexion PHP, l'erreur passe dans JS sur error: alors que si c'est une erreur de requête ça passe sur success:
2 - Pourquoi le traitement JS en Error: donne msg indefined quand j'ai une erreur de connexion PHP et pourquoi la variable retournée de PHP est un objet et non une chaine JSON

Bonne fin de week-end Smiley hippy
Modifié par informer (15 Jun 2014 - 20:17)
Modérateur
Bonjour,

La première chose à faire est de vérifier ce qu'il y a dans $returnData à la fin de ton script php exécuté suite à la requête AJAX (tu peux par exemple juste avant le return à la fin du script écrire ce qu'elle contient dans un fichier sur le serveur).

Que ce soit un message d'erreur ou du json ou n'importe quoi d'autre, ça devrait te permettre déjà de savoir si ce qu'elle contient est bien ce que tu attends. Ensuite seulement, il faut se poser des questions sur ce qui se passe dans la partie javascript.

Amicalement,
Comme j'utilise x-debug avec NetBean, j'ai fait une copie d'écran la 1ère image dans mon texte et tu vois que $retrunData = "{"msg":"SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Hôte inconnu. "}"
Donc bien au format JSON

A+
bonsoir a tous,SVP Smiley ohwell j'ai un table question et réponse sur une base de donnée SQL, et dans un forme web j'ai une label est textbox, je veut afficher dans label un question aléatoire et quand l'utilisateur saisi la réponse exact il affiche autre question aléatoire.
je ne sais comment je peut faire aide moi SVP.et merci d'avance Smiley ohwell
Modérateur
informer a écrit :

Questions:
1- Pourquoi si c'est une erreur sur le host de la chaine de connexion PHP, l'erreur passe dans JS sur error: alors que si c'est une erreur de requête ça passe sur success:
2 - Pourquoi le traitement JS en Error: donne msg indefined quand j'ai une erreur de connexion PHP et pourquoi la variable retournée de PHP est un objet et non une chaine JSON


1) Dans certains cas, l'information renvoyée par le serveur peut être augmentée automatiquement de messages d'erreur (au format HTML en général) (peut-être à cause du session_start(), ou du header() ou je ne sais quoi d'autre), et du coup, ajax/jquery n'arrive plus à traiter cette information et passe donc sur error: au lieu de success:.
2) Quand on est dans error: côté js, ajax/jquery a détecté une erreur, une des raisons possibles est que l'information ne soit pas arrivée sous la forme d'un json (sur ta copie d'écran 52547-error1.jpg, on voit d'ailleurs un statut: "parsererror" en bas, et on aperçoit des trucs bizarres comme valeur de responseText). Du coup, dataSQL peut ne pas avoir de propriété "msg", d'où le msg undefined.

Pour régler ce problème, il faut faire en sorte que le script php renvoie bien du json et bien que ça. A titre de test, dans le script php, tu peux essayer de ne garder que la requête à la base de données et sa réponse mis au format json (sans session_start(), sans error_reporting(), sans ini_set(), sans header(), ...) et tu regardes ce que ça donne.

Amicalement,
Modifié par parsimonhi (16 Jun 2014 - 02:25)
Modérateur
Bonjour,

Pour un peu mieux voir ce qui se passe côté client (ou côté js si tu préfères), tu peux modifier la fonction logIn() comme ci-dessous :


function logIn()
{
	alert("connexion debut");
	try
    {
    	var serialData = $( "#frmLogIn" ).serialize();
		$.ajax
			(   {   type: "POST",
                    url: "logInTest.php",
                    data: serialData,
                    dataType: "json",
                    success: function(dataSQL, statut)
                    {
                    	if (dataSQL["msg"]) alert("success msg: " + dataSQL["msg"]);
                    	else if (dataSQL["responseText"]) alert("success response text: " + dataSQL["responseText"]);
                    	else alert("success data: " + JSON.stringify(dataSQL));
                    },
                    error: function(dataSQL, statut)
                    {
                    	if (dataSQL["msg"]) alert("error msg: " + dataSQL["msg"]);
                    	else if (dataSQL["responseText"]) alert("error response text: " + dataSQL["responseText"]);
                    	else alert("error data: " + JSON.stringify(dataSQL));
                    }
                }
            );
    }
    catch (e)
    {
    	alert ('An error has occurred: '+ e.message);
    }
}


Pour un peu mieux voir ce qui se passe côté serveur, tu peux modifier loginTest.php comme ci-dessous :


//session_start();

//error_reporting(E_ALL);
//ini_set( 'display_errors','1');

require "dbConnect.php";

//header('Content-Type: application/json; charset=utf-8');
$user = urldecode($_POST["txtUser"]);
$pwd = urldecode($_POST["txtpwd"]);

$sqlSelect = " SELECT * FROM participant WHERE USER = '$user' AND PWD = '$pwd'";

try
{   $dbConnect = dbConnection();
    $dataSet = $dbConnect->query($sqlSelect);
    $rowsArray = $dataSet->fetchAll();
    $returnData =  json_encode($rowsArray);    
    //if (count($rowsArray)>0)
    //{   $_SESSION["userID"] = $rowsArray[0]["IDPARTICIPANT"];  
    //}
    $where = "try";
 
}catch (PDOException $e)
{	$stringVar = utf8_encode($e->getMessage());
	$msg =  array("msg" =>  $stringVar);
	$returnData = preg_replace("/\\\\u([a-f0-9]{4})/e", "iconv('UCS-4LE','UTF-8',pack('V', hexdec('U$1')))", json_encode($msg));
	$where = "catch";
   //die();
}

$dbConnect = null;// Fermeture connexion
file_put_contents('log.txt', $where." ".$returnData);
echo $returnData;


Tu regardes ce qui a été envoyé côté serveur dans log.txt et reçu côté client dans les alertes pour au moins 3 cas : erreur de connexion à la base sql, erreur de requête sql, et pas d'erreur sql du tout.

Ensuite, tu dé-commentes les lignes mises en commentaires dans loginTest.php, et tu regardes à nouveau ce qui se passe dans les 3 cas ci-dessus.

A adapter selon tes besoins et contraintes.

Amicalement,
Modifié par parsimonhi (16 Jun 2014 - 09:05)
si ça peut aider, pour débugger de l'ajax, commence par débugger ton fichier php, il faut qu'il retourne le JSON et rien d'autre (vraiment rien d'autre).

Pour l'accent, essaye de passer en htmlentities. Sous un encodage en iso-8859-1, ça suffit à résoudre le problème du json que le javascript ne lit pas avec des accents.
Bonjour à tous,
Nouveau rebondissement. Pour faire un code à l'arrache (merci Parsimonhi pour ton code) j'ai écrit ce code dans error::
 error: function(dataSQL, statut)
                    {   //alert("msg " + dataSQL["msg"]);
                       //var msg0 =  JSON.parse(dataSQL.responseText);
                        var msg = dataSQL.responseText;
                        var msg2 =  msg.match(/(msg.*u.)/);
                        alert(msg2[0]);
                    }

Et pour tester mon regexp, j'ai utilisé RegExp Helper de notepad++ et là le mot hôte apparait comme ci-dessous dans l'image i.e Hôte Smiley mur
upload/52547-regexp.jpg *

Merci aussi Parsimonhi pour la création d'un log qui hélas me donne ceci, c'est fou non Smiley mur
"error : {"msg":"SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Hôte inconnu. "}"
Qui est bien au format JSON (test sur http://jsonlint.com/)

C'est vraiment un problème d'accent et vais tester htmlentities. comme proposé par Lothindil même si déjà fait et sur certains blogs c'est fortement déconseillé (???).

J'ai également testé en désactivant sans session_start(), sans error_reporting(), sans ini_set(), sans header() mais pas plus de réussite !!! Smiley mur

Il est évident que c'est le formatage JSON qui me pose un problème Smiley mur Smiley mur

To be continued Smiley boulet
il paraît que c'est déconseillé... mais je fais passer des textes complets issus de mes tables ou de tableau php ainsi sans le moindre soucis. Si j'ôte mes htmlentities, ça plante invariablement, alors que le json est reconnu comme étant de format valide.

(je parle bien avec un encodage en iso-8859, je ne suis pas certaine qu'en utf-8 ça marche le moins du monde)
Je viens d'essayer
 $stringVar = htmlentities($e->getMessage());


ça retourne vide... Une idée avant de me reconvertir dans la plomberie où on gagne bien sa vie aussi.... Smiley cligne

Adieu monde cruel Smiley fulmine Smiley fulmine
$stringVar = utf8_encode($e->getMessage());
	$msg =  array("msg" =>  $stringVar);
	$returnData = preg_replace("/\\\\u([a-f0-9]{4})/e", "iconv('UCS-4LE','UTF-8',pack('V', hexdec('U$1')))", json_encode($msg));
	$where = "catch";


et si tu changes tout ça en

$stringVar=htmlentities($e->getMessage());
$returnData=array("msg"=>$stringVar);
$returnData=json_encode($returnData);
$where = "catch";
echo returnData;


(j'avoue que je vois pas l'intérêt du preg_replace)
Modérateur
Bonjour,

@informer : qu'est-ce qu'il y a dans dataSQL.responseText (en totalité) ?

Quand je teste chez moi, et que je laisse dé-commenté les lignes ini_set() et header(), et si je fais exprès de générer une erreur de connexion à la base SQL, j'ai dans mon alert() :

error response text: <br />
<b>Warning</b>: Cannot modify header information - headers already sent by (output started at /Users/A/Sites/dbConnect.php:20) in <b>/Users/A/Sites/logInTest.php</b> on line <b>9</b><br />
{"msg":"SQLSTATE[28000] [1045] Access denied for user ...

Ce responseText ne peut pas être décodé par jquery convenablement (il n'est pas au format JSON à cause du message d'erreur ajouté par le serveur devant la partie qui est en JSON), l'exécution dans le js passe du coup par le error:, et dataSQL["msg"] n'existe pas.

Note que quand l'exécution dans le js passe par le error:, ça n'a rien à voir avec une erreur avec la base sql (que ce soit connexion ou autre). Ca veut juste dire que jquery n'arrive pas à décoder le message. Et quand tu écris dans la partie js : var msg = dataSQL.responseText;var msg2 = msg.match(/(msg.*u.)/);alert(msg2[0]);, même si tu sembles voir du JSON dans la variable msg2, ça ne signifie pas que tu as du json dans la variable msg.

Amicalement,
Merci encore à tous pour votre aide

Parsimonhi voici le texte dans responseText = "
<br />
<font size='1'><table class='xdebug-error xe-warning' dir='ltr' border='1' cellspacing='0' cellpadding='1'>
<tr><th align='left' bgcolor='#f57900' colspan="5"><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>( ! )</span> Warning: PDO::__construct():  in C:\wamp\www\projetLaPaire\dbConnect.php on line <i>24</i></th></tr>
<tr><th align='left' bgcolor='#e9b96e' colspan='5'>Call Stack</th></tr>
<tr><th align='center' bgcolor='#eeeeec'>#</th><th align='left' bgcolor='#eeeeec'>Time</th><th align='left' bgcolor='#eeeeec'>Memory</th><th align='left' bgcolor='#eeeeec'>Function</th><th align='left' bgcolor='#eeeeec'>Location</th></tr>
<tr><td bgcolor='#eeeeec' align='center'>1</td><td bgcolor='#eeeeec' align='center'>0.2268</td><td bgcolor='#eeeeec' align='right'>147384</td><td bgcolor='#eeeeec'>{main}(  )</td><td title='C:\wamp\www\projetLaPaire\logInTest.php' bgcolor='#eeeeec'>..\logInTest.php<b>:</b>0</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>2</td><td bgcolor='#eeeeec' align='center'>21.8945</td><td bgcolor='#eeeeec' align='right'>151784</td><td bgcolor='#eeeeec'>dbConnection(  )</td><td title='C:\wamp\www\projetLaPaire\logInTest.php' bgcolor='#eeeeec'>..\logInTest.php<b>:</b>17</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>3</td><td bgcolor='#eeeeec' align='center'>21.8946</td><td bgcolor='#eeeeec' align='right'>152872</td><td bgcolor='#eeeeec'><a href='http://www.php.net/PDO.construct' target='_new'>__construct</a>
( ???, ???, ???, ??? )</td><td title='C:\wamp\www\projetLaPaire\dbConnect.php' bgcolor='#eeeeec'>..\dbConnect.php<b>:</b>24</td></tr>
</table></font>
{"message":"SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Hôte inconnu. "}"

Donc si je te comprends bien, le serveur balance en plus de
{"message":"SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Hôte inconnu. "}"
des infos complémentaires qui ne peuvent pas être interprétées par JQuery, ce qui entraine un traitement en erreur coté client.

Ça mériterait pas un ticket de bug pour Jquery, enfin je suggère mais je sais pas si c'est possible...

Lothindil
Si je passe pas par preg_replace("/\\\\u([a-f0-9]{4})/e", "iconv('UCS-4LE','UTF-8',pack('V', hexdec('U$1')))", json_encode($msg)); je retrouve mon caractère ô sous la forme de /fffud quand j'encode en json sans preg_replace.
Je ne peux te dire pourquoi, par contre ça marche avec et pas sans


Dernière question

Pourquoi var msg2 = msg.match(/(message.*u.)/); => msg2 en Array[2] avec dans chaque ligne le même texte "msg":"SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Hôte inconnu." Smiley eek

C'était ma dernière question mais surement pas la dernière séance !!!
Modifié par informer (16 Jun 2014 - 18:35)
Je continue à dire :

si ça peut aider, pour débugger de l'ajax, commence par débugger ton fichier php, il faut qu'il retourne le JSON et rien d'autre (vraiment rien d'autre).


Tant que ton php retournera autre chose que ton JSON, ton JQuery ne pourra pas l'interpréter.


Ma technique perso :

-> tu simules ce que tu envoies au php (quitte à faire du $_POST['blabla']="foo"; en début de fichier)
-> tu appelles directement ton fichier php dans ton navigateur
-> tu oublies le javascript tant que ton fichier te renvoie autre chose que ton seul message json ^^
Question?

Puisque JQuery ne sait pas traité les données en retour avec un header (si je t'ai bien compris), en utilisant l'objet XMLHttpRequest, le problème ne serait pas résolu?

2ème interrogation, si on passait du XML ou lieu de JSON avec JQuery, cela ne serait pas mieux?

Bonne soirée
Mais c'est bien l'objectif de ce post.

Tu n'es donc pas du même avis que Parsimonhi sur JQuery ?

De plus en forçant le message d'erreur dans le fichier php en pur format JSON (testé sur http://jsonlint.com) :
$returnData = '{"message":"erreur server"}';
echo $returnData;

Je récupère dans responseText toujours un header avant {"message":"erreur server"}" comme ci-dessus (totalité dans précédent post):
"  <br />
<font size='1'><table class='xdebug-error xe-warning' dir='ltr' border='1' cellspacing='0' cellpadding='1'>
....
bgcolor='#eeeeec'><a href='http://www.php.net/PDO.construct' target='_new'>__construct</a>
( ???, ???, ???, ??? )</td><td title='C:\wamp\www\projetLaPaire\dbConnect.php' bgcolor='#eeeeec'>..\dbConnect.php<b>:</b>24</td></tr>
</table></font>
{"message":"erreur server"}"
Que ça soit avec la version JQuery ou la version javascript, ça reste le même principe. Il ne traite que les données json et est incapable de trouver ce qui pourrait peut-être être du JSON parmi autre chose.

Et pour le XML, je suppose que si tu sors autre chose que du XML, ça causera exactement le même soucis.

La question c'est plutôt : pourquoi t'as besoin d'envoyer tout ces trucs avant le json ?
Mais c'est toute la question, pourquoi il y a tout ça avant alors que coté php je fais juste un

$returnData = '{"message":"erreur server"}';
echo $returnData;


Et ce qui n'arrive ps quand ai une erreur sur l'objet quey par exemple.=> Aucun problème d'encodage JSON

La question est sur le comportement de php / ajax quand il y a une erreur server !!!!
Pages :