web-dev-qa-db-fra.com

Comment faire une requête POST Ajax avec Symfony et Jquery

J'ai besoin de stocker des paramètres de carte dans mon projet symfony, pour ce faire, j'ai besoin d'implémenter un Ajax à mon avis qui sera en mesure de transmettre des informations au contrôleur.

J'ai lu les documents, j'essaie d'écrire du code mais je ne peux pas le faire fonctionner. Et Ajax est vraiment pénible à déboguer. Voici la partie contrôleur:

 /**                                                                                   
 * @Route("/ajax", name="_recherche_ajax")
 */
public function ajaxAction()    
{
    $isAjax = $this->get('Request')->isXMLHttpRequest();
    if ($isAjax) {         
        return new Response('This is ajax response');
    }
    return new Response('This is not ajax!', 400);
}

Et le JS:

map.on('zoomend', function(e) {
    // use callback e variable
    console.log('zoom: ' + e.target.getZoom());

    $.ajax({
        type: "POST",
        url: "/recherche/ajax",
        data: {
           zoom: e.target.getZoom()
        },
        dataType: "json",
        success: function(response) {
            console.log(response);
        }
    });

});

Je vérifie l'url recherche/ajax il existe et retourne le 'This is not Ajax' comme prévu. Mais le console.log ne renvoie aucune valeur ...

Est-ce la bonne façon de procéder?

EDIT: Il semble que le contrôleur ne puisse pas gérer POST Request. J'ai essayé de modifier les annotations pour:

 /**                                                                                   
 * @Route("/ajax", name="_recherche_ajax")
 * @Method({"GET", "POST"})
 */

Mais ça revient:

([Semantical Error] The annotation "@Method" in method MySite\SiteBundle\Controller\RechercheController::ajaxAction() was never imported. Did you maybe forget to add a "use" statement for this annotation?) 
14
Xavier

Essaye ça,

/**                                                                                   
 * @Route("/ajax", name="_recherche_ajax")
 */
public function ajaxAction(Request $request)    
{
    if ($request->isXMLHttpRequest()) {         
        return new JsonResponse(array('data' => 'this is a json response'));
    }

    return new Response('This is not ajax!', 400);
}

Si vous envoyez une demande Ajax, vous devez renvoyer json/plaintext/xml des données, et non un objet Response entier.

PS: N'oubliez pas d'ajouter une instruction use pour Request et JsonResponse

EDIT: Comme l'indique le message d'erreur que vous avez ajouté, vous devez importer l'annotation @Method en utilisant :

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;

23
sf_tristanb

Je regardais tout Internet et je n'ai trouvé aucune solution à un problème similaire. Mais je l'ai trouvé-> Je n'ai eu ni problème avec le contrôleur, ni javascript/jquery/ajax ni les problèmes de sécurité. C'était en .... attendez ... en HTML. j'ai dû ajouter type = "button" dans la balise html, sinon la page entière était rafraîchissante. 4 heures gaspillées à des fins de débogage .. mais leçons apprises.

Comment déboguer des problèmes? 1. Vérifiez si ajax envoie des messages et des itinéraires de messages correspondants du côté client. Firefox -> f12 -> réseau -> regardez les événements POST 2. Vérifiez le profileur symfony (outil très utile!) Sur le -> /app_dev.php/ (environnement de développement) -> Get La fin du sous-menu Request/Response prend les 10 dernières, si vous voyez la route POST vérifier de près si son code de retour et ses paramètres (vous ne verrez pas de réponse, si son ensemble est différent de la réponse HTML) 3. Dans votre le contrôleur effectue une action qui peut être vérifiée si le script à l'intérieur de cette route a été exécuté. Si c'est le cas, et vous ne voyez aucune réponse du côté du serveur (contrôleur) ou du client (twig/ajax/html) 4. Exemples de code:

Bouton en html (c'était mon problème)

<button name="button" id="button" class="button" type="button" value="100"> Click me </button> 

Ajax en html ou autre fichier js inclus:

function aButtonPressed(){
        $.post('{{path('app_tags_sendresponse')}}',
            {data1: 'mydata1', data2:'mydata2'},
            function(response){
                if(response.code === 200 && response.success){
                    alert('success!');
                }
                else{
                    alert('something broken');
                }
            }, "json");
    }

Maintenant .. côté serveur. Manette:

namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class JsonApiController extends Controller
    /**
         * @Route("/api/programmers")
         * @Method("POST")
         */
        public function sendResponse()
        {
            if(isset($_POST['data1'])){
                $json = json_encode(array('data' => $_POST['data1']), JSON_UNESCAPED_UNICODE);
                file_put_contents("test.json", $json);
                return new JsonResponse($json);
            }
            return new Response('didn't set the data1 var.');
        }
    }

File put contents crée un nouveau fichier dans le répertoire web. S'il a été mis en correspondance et qu'un fichier est créé, cela signifie que vous avez mis en correspondance l'itinéraire, mais n'avez pas obtenu la réponse.

2
Błażej Krzakala