IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

AJAX Discussion :

Envoyer du JSON au serveur via POST


Sujet :

AJAX

  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    521
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 521
    Points : 136
    Points
    136
    Par défaut Envoyer du JSON au serveur via POST
    Bonjour.

    J'ai besoin d'envoyer une série de valeurs que j'ai récupéré depuis le serveur comme ceci afin de les utiliser en javascript :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    $reponse = $mysql_connect->query('SELECT * FROM mydatabase' );
    		while ($test = $reponse->fetch() ){
    			?>
    				<?php if ( $test['pseudo'] == $_SESSION['pseudo'] ){
                                            echo '<script>var donnees = '.json_encode($test).' ;</script>';
                                    }
                                    ?>
    			<?php
    		}
    pour les envoyer j'utilise une requete XMLHttpRequest :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    var xhr = getXMLHttpRequest(); 
    		xhr.open("POST", "savedatas.php", true);
    		xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    		xhr.send(JSON.stringify(donnees));
    et enfin j'essaye de les récupérer depuis ma page php :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    <?php
     
      $data = json_decode($_POST);
            
            if (isset($data["id"])) {
                    try{
                            $mysql_connect = new PDO('mysql:host=www.monsite.com;dbname=dtbtest','test', 'test');
                            $mysql_connect -> exec( 'UPDATE mydatabase SET value= '.$data["value"].' WHERE pseudo = '.$data["pseudo"].' '); 
                    }
                    catch(Exception $e){
                    }
                    echo "OK";
            }
     
    ?>
    Malheureusement, ça ne fonctionne pas.
    Si je passe manuellement moi même une donnée exemple "pseudo=mazerty&value=17" par contre ça marche.



    Savez vous, donc, comment faire passer un objet json via POST ?

    Merci

  2. #2
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Salut,
    pourquoi tu ne filtres pas ta première requête SQL avec un WHERE ?

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <?php
    $reponse = $mysql_connect->prepare('SELECT * FROM mydatabase WHERE pseudo = ?');
    $reponse->execute([ $_SESSION['pseudo'] ]);
    while ($test = $reponse->fetch()) {
        ...
    }

    De plus, tu peux grouper les générations de code JavaScript à la fin de la boucle.
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while ($test = $reponse->fetch()) {
        $donnees[] = $test;
    }
    echo '<script>var donnees = '.json_encode($donnees).' ;</script>';

    Alternativement, tu peux utiliser fetchAll().
    Et si la requête est censée renvoyer toujours une seule ligne, tu n’as pas besoin de boucle.

    Pense à paramétrer ton fetch mode pour réduire le volume de données, à la fois dans la mémoire du processus PHP et dans l’objet JSON produit. Les différents modes sont décrits sur la page de fetch(). Je te conseille FETCH_ASSOC ou FETCH_NAMED.

    À propos de ton code JS :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    var xhr = getXMLHttpRequest();
    xhr.open("POST", "savedatas.php", true);
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    xhr.send(JSON.stringify(donnees));
    Ici, le type annoncé "application/x-www-form-urlencoded" et le type réel (JSON) ne correspondent pas. Le serveur attend une syntaxe clé1=valeur1&clé2=valeur2 et à la place il reçoit quelque chose comme {"clé1":"valeur1","clé2":"valeur2"}.

    Tu as trois solutions :
    1. Garder le type "application/x-www-form-urlencoded" et préfixer les données avec une clé POST :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      xhr.send("json=" + encodeURIComponent(JSON.stringify(donnees)));
      Code php : Sélectionner tout - Visualiser dans une fenêtre à part
      $data = json_decode($_POST['json']);
    2. Toujours avec le type "application/x-www-form-urlencoded", décomposer l’objet JSON (avec une fonction JavaScript écrite par toi-même) et envoyer directement son contenu au format clé1=valeur1&clé2=valeur2.
    3. Changer le type pour "application/json", et utiliser 'php://input' dans ton script serveur.
      Code php : Sélectionner tout - Visualiser dans une fenêtre à part
      $data = json_decode(file_get_contents('php://input'));


    Attention dans ta seconde requête SQL, grosse vulnérabilité !
    • Tu n’utilises pas prepare() ;
    • Tu utilises directement des données provenant du client sans les contrôler.


    Au minimum, assure-toi au moins que $data['pseudo'] correspond à $_SESSION['pseudo'] ou quelque chose comme ça.

    N’importe qui avec un navigateur moderne peut modifier une requête ajax via la console et envoyer des données malveillantes. Voici un exemple de JSON qui effacerait toutes les données value de ta table :
    Code json : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    {
      "id":42,
      "value":0,
      "pseudo":"'OR TRUE;--"
    }
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  3. #3
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    521
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 521
    Points : 136
    Points
    136
    Par défaut
    Merci pour ta réponse Watilin !

    Malheureusement cela ne fonctionne pas (en ce qui concerne la solution 1 et 3 ).

    Si j'essaye de caller l'ensemble des données en utiliant encodeURIComponent, cela produit, au niveau du texte envoyé, quelque chose comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     %7B%220%22%3A%2215%22%2C%221%22%3A%22mazertys%22%2C%222%22%3A%222019-07-09%2009%3A24%3A58%22%2C%223%22%3A%221564139505787%22%2C%224%22%3A%221.4%22%2C%225%22%3A%227%22%2C%226%22%3A%220%22%2C%227%22%3A%220%22%2C%228%22%3A%2217%22%2C%229%22%3A%2217%22%2C%2210%22%3A%220%22%2C%22id%22%3A%2215%22%2C%22pseudo%22%3A%22mazertys%22%2C%22datecreation%22%3A%222019-07-09%2009%3A24%3A58%22%2C%22lastTime%22%3A1564146925941%2C%22eauFlux%22%3A%221.4%22%2C%22population%22%3A%227%22%2C%22natalite%22%3A%220%22%2C%22populationFlux%22%3A%220%22%2C%22credit%22%3A364.2527777777778%2C%22habitation%22%3A%2217%22%2C%22constructionHabitation%22%3A%220%22%7D
    et me dit ceci dans le débug :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     HTTP500: ERREUR DE SERVEUR. Le serveur ne peut pas exécuter la requête, car il a rencontré une condition inattendue.
    (XHR)POST - https://www.monsite.comt/savedatas.php

    ...pour la solution 3, il me dit la même chose au débug, et (vu que je suis débutant) je ne savais pas s'il fallait utiliser JSON.stringify(datas) ou simplement mettre les datas du coup j'ai essayé les 2 mais sans succès.


    Quand à la 2ème option, j'y ai pensé...cependant à mon niveau cela me paraît trop hasardeux et long à faire alors que je suis sur qu'il existe des fonctions faites pour ça donc je préfère éviter cela autant que possible !

  4. #4
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    C’est bizarre, une erreur 500 normalement ça indique un problème de configuration du serveur.

    Est-ce que les codes suivants fonctionnent ? Utilise l’onglet réseau de la console pour voir les corps des requêtes et des réponses.

    Solution 1
    Code JS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    const req = new XMLHttpRequest();
    req.open("POST", "testpost.php");
    req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    req.send("json=%7B%220%22%3A%2215%22%2C%221%22%3A%22mazertys%22%2C%222%22%3A%222019-07-09%2009%3A24%3A58%22%2C%223%22%3A%221564139505787%22%2C%224%22%3A%221.4%22%2C%225%22%3A%227%22%2C%226%22%3A%220%22%2C%227%22%3A%220%22%2C%228%22%3A%2217%22%2C%229%22%3A%2217%22%2C%2210%22%3A%220%22%2C%22id%22%3A%2215%22%2C%22pseudo%22%3A%22mazertys%22%2C%22datecreation%22%3A%222019-07-09%2009%3A24%3A58%22%2C%22lastTime%22%3A1564146925941%2C%22eauFlux%22%3A%221.4%22%2C%22population%22%3A%227%22%2C%22natalite%22%3A%220%22%2C%22populationFlux%22%3A%220%22%2C%22credit%22%3A364.2527777777778%2C%22habitation%22%3A%2217%22%2C%22constructionHabitation%22%3A%220%22%7D");
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <?php // testpost.php
    header('Content-Type: text/plain; charset=utf-8');
    ini_set('html_errors', '0');
    print_r($_POST);

    Solution 3
    Code JS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    const req = new XMLHttpRequest();
    req.open("POST", "testinput.php");
    req.setRequestHeader("Content-Type", "application/json");
    req.send('"{"0":"15","1":"mazertys","2":"2019-07-09 09:24:58","3":"1564139505787","4":"1.4","5":"7","6":"0","7":"0","8":"17","9":"17","10":"0","id":"15","pseudo":"mazertys","datecreation":"2019-07-09 09:24:58","lastTime":1564146925941,"eauFlux":"1.4","population":"7","natalite":"0","populationFlux":"0","credit":364.2527777777778,"habitation":"17","constructionHabitation":"0"}"');
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <?php // testinput.php
    header('Content-Type: text/plain; charset=utf-8');
    ini_set('html_errors', '0');
    echo file_get_contents('php://input');

    Pour la solution 2, j’imagine que jQuery fait ça, je n’ai pas regardé en détails. On devrait sans doute trouver un certain nombre de biblis sur npm qui font ça également. Le fait est qu’il n’y a pas de fonction native pour ça. La fonction qu’il faudrait écrire est une fonction récursive, c’est toujours un exercice intéressant. Dans les grandes lignes, ce serait une fonction qui prend un argument, et qui :
    • examine le type de l’argument ;
    • si c’est un type primitif et compatible JSON, renvoie sa valeur JSON équivalente (tous les types ne sont pas compatibles JSON, par exemple "undefined" et "function") – on n’oubliera pas d’encoder pour URL avec encodeURIComponent ;
    • si c’est un type d’objet, il faut alors vérifier :
      • si ce n’est pas null
      • si c’est un tableau – dans ce cas il faut parcourir chaque valeur et appeler récursivement la fonction dessus
      • sinon, c’est un objet « classique » et il faut parcourir les paires clé-valeur (par exemple avec Object.entries) et, comme au-dessus, faire un appel récursif pour chaque valeur

      Et à la fin on stringify, on encode et on colle tout ça avec du scotch (= et &).

    C’est normal que tu trouves ça compliqué, et vu la spécificité de l’usage, et l’existence de solutions alternatives, ça pourrait expliquer pourquoi il n’y a pas de fonction native qui fait ça.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

Discussions similaires

  1. Réponses: 1
    Dernier message: 18/04/2015, 22h05
  2. Peut-on envoyer du json au serveur
    Par arsene555 dans le forum jQuery
    Réponses: 8
    Dernier message: 13/07/2011, 14h56
  3. Récupérer une image envoyée au serveur en POST
    Par ultracoxy dans le forum Java ME
    Réponses: 9
    Dernier message: 28/12/2007, 11h49
  4. Réponses: 7
    Dernier message: 14/08/2007, 17h45
  5. [AJAX] Retrouver xml envoyé du client au serveur (via méthode POST)
    Par leszek dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 20/05/2006, 16h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo