6719 votes

Comment retourner la réponse d'un appel Ajax ?

J'ai une fonction foo qui effectue une requête Ajax. Comment puis-je renvoyer la réponse de foo ?

J'ai essayé de renvoyer la valeur de la success ainsi que l'assignation de la réponse à une variable locale dans la fonction et le retour de celle-ci, mais aucune de ces méthodes ne renvoie réellement la réponse.

function foo() {
    var result;

    $.ajax({
        url: '...',
        success: function(response) {
            result = response;
            // return response; // <- tried that one as well
        }
    });

    return result;
}

var result = foo(); // always ends up being `undefined`.

6646voto

Felix Kling Points 247451

-> Pour une explication plus générale du comportement asynchrone avec différents exemples, voir Pourquoi ma variable reste-t-elle inchangée après que je l'ai modifiée à l'intérieur d'une fonction ? - Référence du code asynchrone

-> Si vous comprenez déjà le problème, passez aux solutions possibles ci-dessous.

Explication du problème

Le site A dans AJAX signifie asynchrone . Cela signifie que l'envoi de la demande (ou plutôt la réception de la réponse) est retiré du flux d'exécution normal. Dans votre exemple, $.ajax retourne immédiatement et l'instruction suivante, return result; est exécutée avant la fonction que vous avez passée comme success le rappel a été appelé.

Voici une analogie qui, nous l'espérons, rendra plus claire la différence entre flux synchrone et asynchrone :

Synchrone

Imaginez que vous passiez un appel téléphonique à un ami et que vous lui demandiez de chercher quelque chose pour vous. Bien que cela puisse prendre un certain temps, vous attendez au téléphone, le regard dans le vide, jusqu'à ce que votre ami vous donne la réponse dont vous aviez besoin.

La même chose se produit lorsque vous faites un appel de fonction contenant du code "normal" :

function findItem() {
    var item;
    while(item_not_found) {
        // search
    }
    return item;
}

var item = findItem();
// do something with item
doSomethingElse();

Même si findItem pourrait prendre beaucoup de temps à s'exécuter, tout code venant après var item = findItem(); doit attendre jusqu'à ce que la fonction renvoie le résultat.

Asynchrone

Vous rappelez votre ami pour la même raison. Mais cette fois, vous lui dites que vous êtes pressé et qu'il devrait vous rappeler sur votre téléphone portable. Vous raccrochez, quittez la maison et faites ce que vous aviez prévu de faire. Lorsque votre ami vous rappelle, vous vous occupez des informations qu'il vous a données.

C'est exactement ce qui se passe lorsque vous faites une requête AJAX.

findItem(function(item) {
    // do something with item
});
doSomethingElse();

Au lieu d'attendre la réponse, l'exécution continue immédiatement et la déclaration après l'appel AJAX est exécutée. Pour obtenir la réponse éventuellement, vous fournissez une fonction à appeler une fois que la réponse a été reçue, une fonction rappel (Vous avez remarqué quelque chose ? rappeler ?). Toute instruction venant après cet appel est exécutée avant que le callback ne soit appelé.


Solutions

Il y a essentiellement deux façons de résoudre ce problème :

  1. Rendre l'appel AJAX synchrone (appelons-le SJAX ).
  2. Restructurez votre code pour qu'il fonctionne correctement avec les callbacks.

1. Appels AJAX synchrones -- NE PAS LE FAIRE

Il est généralement une mauvaise idée pour rendre les appels AJAX synchrones. NE LE FAITES PAS. Je suis sérieux. Je ne le mentionne ici que par souci d'exhaustivité. Pourquoi est-ce mauvais, me demandez-vous ?

JavaScript s'exécute dans le fil d'exécution de l'interface utilisateur du navigateur et tout processus qui s'éternise bloque l'interface utilisateur, la rendant peu réactive. En outre, il existe une limite supérieure au temps d'exécution de JavaScript et le navigateur demande à l'utilisateur s'il souhaite poursuivre l'exécution ou non. Tout cela constitue une très mauvaise expérience pour l'utilisateur. L'utilisateur ne sera pas en mesure de dire si tout fonctionne bien ou non. De plus, l'effet sera pire pour les utilisateurs ayant une connexion lente.

jQuery

Si vous utilisez jQuery vous pouvez régler le async option pour false . Notez que cette option est déprécié depuis jQuery 1.8. Vous pouvez alors soit toujours utiliser un success ou accéder au responseText de l Objet jqXHR :

function foo() {
    var jqXHR = $.ajax({
        //...
        async: false
    });
    return jqXHR.responseText;
}

Si vous utilisez une autre méthode AJAX de jQuery, telle que $.get , $.getJSON etc., vous devez le changer en $.ajax (puisque vous ne pouvez transmettre des paramètres de configuration qu'à $.ajax ).

Attention ! Il n'est pas possible de faire un JSONP demande. Par sa nature même, JSONP est toujours asynchrone (une raison de plus pour ne pas envisager cette option).

Sans jQuery

Si vous utilisez directement un XMLHTTPRequest passe false comme troisième argument à .open .

2. Restructurer le code

Laisser les fonctions accepter les callbacks

La meilleure approche consiste à organiser correctement votre code autour de callbacks. Dans l'exemple de la question, vous pouvez rendre foo accepte un callback et l'utilise comme success de rappel. Donc, ceci

var result = foo();
// code that depends on 'result'

devient

foo(function(result) {
    // code that depends on 'result'
});

Ici, nous passons une fonction comme argument à foo . Vous pouvez passer n'importe quelle référence de fonction, par exemple :

function myCallback(result) {
    // code that depends on 'result'
}

foo(myCallback);

foo est défini comme suit :

function foo(callback) {
    $.ajax({
        // ...
        success: callback
    });
}

callback fera référence à la fonction que nous passons à foo quand nous l'appelons et nous le passons simplement à success . C'est-à-dire une fois que la requête AJAX est réussie, $.ajax appellera callback et transmet la réponse à la fonction de rappel (qui peut être désignée par l'expression result puisque c'est ainsi que nous avons défini la fonction de rappel).

Vous pouvez également traiter la réponse avant de la transmettre au callback :

function foo(callback) {
    $.ajax({
        // ...
        success: function(response) {
            // e.g. filter the response
            callback(filtered_response);
        }
    });
}

Il est plus facile d'écrire du code en utilisant des callbacks qu'il n'y paraît. Après tout, JavaScript dans le navigateur est fortement axé sur les événements (événements DOM). La réception de la réponse AJAX n'est rien d'autre qu'un événement.
Des difficultés peuvent survenir lorsque vous devez travailler avec du code tiers, mais la plupart des problèmes peuvent être résolus en réfléchissant simplement au flux de l'application.

Utiliser des objets différés / promesses

Si le passage direct des callbacks fonctionne très bien, il peut devenir inflexible dans certaines situations. Objets différés / promesses sont un excellent moyen de gérer de nombreux callbacks et de découpler votre code.

Objets différés ne sont pas unique à jQuery (voir aussi le Proposition Promise/A ) et il existe de nombreuses implémentations indépendantes, mais je me concentrerai uniquement sur jQuery dans cette réponse.

Heureusement pour nous, chaque méthode AJAX de jQuery renvoie déjà une promesse que vous pouvez simplement renvoyer depuis votre fonction et le code appelant décide comment attacher les callbacks :

function foo() {
    return $.ajax(...);
}

foo().done(function(result) {
    // code depending on result
}).fail(function() {
    // an error occurred
});

La description de tous les avantages qu'offrent les objets différés dépasse le cadre de cette réponse, mais si vous écrivez un nouveau code, vous devriez sérieusement les prendre en considération. Ils fournissent une grande abstraction et une séparation de votre code.

Améliorer le mauvais code

Les Deferreds peuvent faciliter la transformation de code asynchrone cassé en code fonctionnel. Par exemple, supposons que vous ayez le code suivant :

function checkPassword() {
    return $.ajax({
        url: '/password',
        data: {
            username: $('#username').val()
            password: $('#password').val()
        },
        type: 'POST',
        dataType: 'json'
    });
}

if (checkPassword()) {
    // Tell the user they're logged in
}

Ce code ne comprend pas les problèmes d'asynchronie mentionnés ci-dessus. Plus précisément, $.ajax() ne fige pas le code pendant qu'il vérifie la page '/password' sur votre serveur - il envoie une requête au serveur et, pendant qu'il attend, renvoie immédiatement un objet jQuery Ajax Deferred, ce qui signifie que votre instruction if obtiendra toujours cet objet Deferred, considérez-le comme true et procéder comme si l'utilisateur était connecté. Ce n'est pas bon.

Mais la solution est simple :

checkPassword()
.done(function(r) {
    if (r) {
        // Tell the user they're logged in
    } else {
        // Tell the user their password was bad
    }
})
.fail(function(x) {
    // Tell the user something bad happened
});

Donc maintenant, nous appelons toujours la page '/password' sur le serveur, mais notre code gère maintenant correctement le temps d'attente pour que le serveur réponde. Le site $.ajax() renvoie toujours immédiatement un objet jQuery Ajax Deferred, mais nous l'utilisons pour attacher des écouteurs d'événements à l'objet .done() et .fail() . Dans le .done() où le serveur a répondu par une réponse normale (HTTP 200), nous vérifions l'objet renvoyé par le serveur. Dans cet exemple, le serveur renvoie juste true si la connexion est réussie, false sinon, donc if (r) vérifie si c'est vrai ou faux.

Dans le .fail() nous sommes confrontés à un problème - par exemple, si l'utilisateur perd sa connexion Internet pendant qu'il saisit son nom d'utilisateur et son mot de passe, ou si votre serveur tombe en panne.

96 votes

@Pommy : Si vous voulez utiliser jQuery, vous devez l'inclure. Veuillez vous référer à docs.jquery.com/Tutoriels:Démarrer_avec_jQuery .

23 votes

Dans la solution 1, sous jQuery, je n'ai pas pu comprendre cette ligne : If you use any other jQuery AJAX method, such as $.get, $.getJSON, etc., you have them to $.ajax. (Oui, je réalise que mon surnom est un peu ironique dans ce cas).

47 votes

@gibberish : Mmmh, je ne sais pas comment le rendre plus clair. Est-ce que tu vois comment foo est appelé et une fonction lui est passée ( foo(function(result) {....}); ) ? result est utilisé à l'intérieur de cette fonction et est la réponse de la requête Ajax. Pour faire référence à cette fonction, le premier paramètre de foo est appelé callback et affecté à success au lieu d'une fonction anonyme. Donc, $.ajax appellera callback lorsque la demande a abouti. J'ai essayé de l'expliquer un peu plus.

1228voto

Benjamin Gruenbaum Points 51406

Si vous êtes pas en utilisant jQuery dans votre code, cette réponse est pour vous

Votre code devrait ressembler à quelque chose comme ceci :

function foo() {
    var httpRequest = new XMLHttpRequest();
    httpRequest.open('GET', "/echo/json");
    httpRequest.send();
    return httpRequest.responseText;
}

var result = foo(); // always ends up being 'undefined'

Felix Kling a fait un excellent travail en écrivant une réponse pour les personnes utilisant jQuery pour AJAX, j'ai décidé de fournir une alternative pour les personnes qui ne le font pas.


Ce à quoi vous êtes confronté

Il s'agit d'un bref résumé de l'"Explication du problème" de l'autre réponse. Si vous n'êtes pas sûr après avoir lu ceci, lisez cela.

Le site A dans AJAX signifie asynchrone . Cela signifie que l'envoi de la demande (ou plutôt la réception de la réponse) est retiré du flux d'exécution normal. Dans votre exemple, .send retourne immédiatement et l'instruction suivante, return result; est exécutée avant la fonction que vous avez passée comme success le rappel a été appelé.

Cela signifie que lorsque vous retournez, le listener que vous avez défini n'a pas encore été exécuté, ce qui signifie que la valeur que vous retournez n'a pas été définie.

Voici une analogie simple

function getFive(){ 
    var a;
    setTimeout(function(){
         a=5;
    },10);
    return a;
}

(Violon)

La valeur de a retourné est undefined depuis le a=5 n'a pas encore été exécutée. AJAX agit de la sorte, vous renvoyez la valeur avant que le serveur n'ait eu la possibilité de dire à votre navigateur quelle est cette valeur.

Une solution possible à ce problème est de coder réactivement qui indique à votre programme ce qu'il doit faire lorsque le calcul est terminé.

function onComplete(a){ // When the code completes, do this
    alert(a);
}

function getFive(whenDone){ 
    var a;
    setTimeout(function(){
         a=5;
         whenDone(a);
    },10);
}

C'est ce qu'on appelle CPS . En gros, on passe getFive une action à exécuter lorsqu'elle se termine, nous indiquons à notre code comment réagir lorsqu'un événement se termine (comme notre appel AJAX, ou dans ce cas le délai d'attente).

L'usage serait :

getFive(onComplete);

Ce qui devrait alerter "5" à l'écran. (Violon) .

Solutions possibles

Il y a essentiellement deux façons de résoudre ce problème :

  1. Rendez l'appel AJAX synchrone (appelons-le SJAX).
  2. Restructurez votre code pour qu'il fonctionne correctement avec les callbacks.

1. AJAX synchrone - Ne le faites pas !

Quant à AJAX synchrone, ne le faites pas ! La réponse de Felix soulève des arguments convaincants pour expliquer pourquoi c'est une mauvaise idée. Pour résumer, cela va geler le navigateur de l'utilisateur jusqu'à ce que le serveur renvoie la réponse et créer une très mauvaise expérience utilisateur. Voici un autre court résumé tiré de MDN sur les raisons de cette situation :

XMLHttpRequest prend en charge les communications synchrones et asynchrones. En général, cependant, les demandes asynchrones doivent être préférées aux demandes synchrones pour des raisons de performances.

En bref, les requêtes synchrones bloquent l'exécution du code... ...ce qui peut causer de sérieux problèmes...

Si vous ont pour le faire, vous pouvez passer un drapeau : Voici comment :

var request = new XMLHttpRequest();
request.open('GET', 'yourURL', false);  // `false` makes the request synchronous
request.send(null);

if (request.status === 200) {// That's HTTP for 'ok'
  console.log(request.responseText);
}

2. Restructurer le code

Laissez votre fonction accepter un callback. Dans l'exemple de code foo peut accepter un rappel. Nous allons indiquer à notre code comment réagir quand foo complète.

Donc :

var result = foo();
// code that depends on `result` goes here

Devient :

foo(function(result) {
    // code that depends on `result`
});

Ici, nous avons transmis une fonction anonyme, mais nous pourrions tout aussi bien transmettre une référence à une fonction existante, ce qui donnerait un résultat similaire :

function myHandler(result) {
    // code that depends on `result`
}
foo(myHandler);

Pour plus de détails sur la façon dont ce type de conception de rappel est réalisé, consultez la réponse de Felix.

Maintenant, définissons foo lui-même pour agir en conséquence.

function foo(callback) {
    var httpRequest = new XMLHttpRequest();
    httpRequest.onreadystatechange = function(){
        if (httpRequest.readyState === 4) {// request is done
            if (httpRequest.status === 200) {// successfully
                callback(httpRequest.responseText);// we're calling our method
            }
        }
    };
    httpRequest.open('GET', "/echo/json");
    httpRequest.send();
}

(violon)

Nous avons maintenant fait en sorte que notre fonction foo accepte une action à exécuter lorsque l'AJAX se termine avec succès, nous pouvons étendre cela en vérifiant si le statut de la réponse n'est pas 200 et agir en conséquence (créer un gestionnaire d'échec et autres). Ce qui résout efficacement notre problème.

Si vous avez toujours du mal à comprendre ceci lire le guide de démarrage d'AJAX à MDN.

32 votes

"les demandes synchrones bloquent l'exécution du code et peuvent provoquer des fuites de mémoire et d'événements" comment une demande synchrone peut-elle provoquer des fuites de mémoire ?

13 votes

@MatthewG J'ai ajouté une prime dessus dans cette question Je vais voir ce que je peux pêcher. En attendant, j'enlève la citation de la réponse.

20 votes

Juste pour la référence, XHR 2 nous permet d'utiliser l'option onload qui ne se déclenche que lorsque readyState es 4 . Bien sûr, il n'est pas pris en charge par IE8. (iirc, peut avoir besoin d'une confirmation).

454voto

cocco Points 3958

XHR2 (lisez d'abord les réponses de Benjamin Gruenbaum et Felix King)

Si vous n'utilisez pas jQuery, et que vous voulez un XHR2 court et agréable qui fonctionne sur les navigateurs modernes et également sur les navigateurs mobiles, je vous suggère de l'utiliser de cette façon.

function ajax(a,b,c){ // Url, Callback, just a placeholder
 c=new XMLHttpRequest;
 c.open('GET',a);
 c.onload=b;
 c.send()
}

Comme vous pouvez le voir :

  1. Elle est plus courte que toutes les autres fonctions listées.
  2. Le callback est défini directement (donc pas de fermetures supplémentaires inutiles).
  3. Il utilise le nouveau onload (ainsi vous n'avez pas à vérifier le readystate && status)
  4. il y a d'autres situations dont je ne me souviens pas qui rendent le xhr1 ennuyeux.

Il y a 2 façons d'obtenir la réponse de cet appel ajax (3 en utilisant le nom de la variable xhr) :

Le plus simple

this.response

ou si pour une raison quelconque vous bind() le rappel d'une classe

e.target.response

Exemple

function callback(e){
 console.log(this.response);
}
ajax('URL',callback);

ou (la solution ci-dessus est meilleure, les fonctions anonymes posent toujours problème)

ajax('URL',function(e){console.log(this.response)});

Rien de plus facile.

Certains diront probablement qu'il est préférable d'utiliser onreadystatechange ou même le nom de la variable XMLHttpRequest. C'est faux.

Regarde ça : http://caniuse.com/xhr2

supporté par tous les navigateurs *modernes. Et je peux confirmer car j'utilise cette approche depuis que xhr2 existe. Je n'ai jamais eu aucun type de problème sur tous les navigateurs que j'utilise.

onreadystatechange n'est utile que si vous voulez obtenir les en-têtes à l'état 2.

Utilisation de la XMLHttpRequest Le nom de la variable est une autre erreur importante, car vous devez exécuter le rappel à l'intérieur des fermetures onload/oreadystatechange, sinon vous le perdez.


Maintenant, si vous voulez quelque chose de plus complexe en utilisant post et FormData, vous pouvez facilement étendre cette fonction :

function x(a,b,e,d,c){ // Url,callback,method,formdata or {key:val},placeholder
 c=new XMLHttpRequest;
 c.open(e||'get',a);
 c.onload=b;
 c.send(d||null)
}

Encore une fois ... c'est une fonction très courte mais elle permet d'obtenir & post

des exemples d'utilisation :

x(url,callback);//by default it's get so no need to set
x(url,callback,'post',{'key':'val'}); //no need to set post data

ou passer un élément de formulaire complet ( document.getElementsByTagName('form')[0] )

var fd=new FormData(form);
x(url,callback,'post',fd);

ou définissez des valeurs personnalisées

var fd=new FormData();
fd.append('key','val')
x(url,callback,'post',fd);

Comme vous pouvez le voir, je n'ai pas mis en œuvre la synchronisation... c'est une mauvaise chose.

Ceci dit... pourquoi ne pas le faire de la manière la plus simple ?


Comme mentionné dans le commentaire, l'utilisation de error && synchronous rompt complètement le point de la réponse, qui est un moyen court et agréable d'utiliser ajax de la manière appropriée.

Gestionnaire d'erreurs

function x(a,b,e,d,c){ // URL,callback,method,formdata or {key:val},placeholder
 c=new XMLHttpRequest;
 c.open(e||'get',a);
 c.onload=b;
 c.onerror=error;
 c.send(d||null)
}
function error(e){
 console.log('--Error--',this.type);
 console.log('this: ',this);
 console.log('Event: ',e)     
}
function displayAjax(e){
 console.log(e,this);
}
x('WRONGURL',displayAjax);

Dans le script ci-dessus, vous avez un gestionnaire d'erreur qui est défini statiquement afin de ne pas compromettre la fonction. Le gestionnaire d'erreurs peut également être utilisé pour d'autres fonctions.

Mais pour vraiment sortir une erreur le uniquement est d'écrire une mauvaise URL, auquel cas tous les navigateurs affichent une erreur.

les gestionnaires d'erreurs sont peut-être utiles si vous définissez des en-têtes personnalisés, si vous définissez le type de réponse (responseType) à blob arraybuffer ou autre.....

Même si vous passez 'POSTAPAPAP' comme methot, il n'y aura pas d'erreur.

Même si vous passez 'fdggdgilfdghfldj' comme données de formulaire, il n'y aura pas d'erreur.

Dans le premier cas, l'erreur se trouve à l'intérieur du displayAjax() sous this.statusText comme Method not Allowed .

Dans le second cas, cela fonctionne tout simplement. Vous devez vérifier du côté du serveur si vous avez passé les bonnes données de post.

crossdomain not allowed lance automatiquement une erreur.

Dans la réponse d'erreur, il n'y a pas de code d'erreur.

Il n'y a que le this.type qui a la valeur "erreur".

Pourquoi ajouter un gestionnaire d'erreurs si vous n'avez absolument aucun contrôle sur les erreurs ? La plupart des erreurs sont renvoyées à l'intérieur de cette fonction de rappel. displayAjax()

Donc : PAS besoin de contrôles d'erreurs si vous êtes capable de copier et coller l'url correctement ;)

ps. : Comme premier test, j'ai écrit x('x',displayAjax)... et j'ai obtenu une réponse... ??? alors j'ai vérifié le dossier où se trouve le HTML... et il y avait un fichier appelé 'x.xml'... donc même si vous oubliez l'extension de votre fichier xhr2 LE TROUVERA J'ai ri.


Lire un fichier de manière synchrone

Ne fais pas ça.

si vous voulez bloquer le navigateur pendant un certain temps, chargez un gros fichier txt synchrone.

function omg(a,c){ // Url
 c=new XMLHttpRequest;
 c.open('GET',a,true);
 c.send();
 return c; //or c.response 
}

maintenant vous pouvez faire

 var res=omg('thisIsGonnaBlockThePage.txt');

Il n'y a pas d'autre moyen de faire cela de manière non asynchrone (oui avec la boucle setTimeout... mais srsly ?).

Un autre point est si vous travaillez avec des API ou juste vos propres fichiers de liste ou autre, vous utilisez toujours des fonctions différentes pour chaque demande

Seulement si vous avez une page où vous chargez toujours le même XML/JSON ou autre, vous n'avez besoin que d'une seule fonction, dans ce cas modifiez un peu la fonction ajax et remplacez b par votre fonction spéciale.


les fonctions ci-dessus sont destinées à une utilisation de base.

si vous voulez EXTENSIONNER la fonction ...

oui, vous pouvez

J'utilise beaucoup d'API et l'une des premières fonctions que j'intègre dans chaque page html est la première fonction ajax de cette réponse ... avec GET seulement...

mais vous pouvez faire beaucoup de choses avec xhr2 :

J'ai fait un gestionnaire de téléchargement (en utilisant des plages des deux côtés avec resume,filereader,filesystem),divers convertisseurs de redimensionnement d'images en utilisant canvas,alimenter des bases de données websql avec des images base64 et bien plus encore... mais dans ces cas vous devriez créer une fonction uniquement dans ce but... parfois vous avez besoin de blob, de arraybuffers, vous pouvez définir des en-têtes, remplacer mimetype et il y a beaucoup plus encore...

mais la question ici est de savoir comment retourner une réponse Ajax ... (j'ai ajouté un moyen simple)

22 votes

Bien que cette réponse soit agréable (et nous avons tous amour XHR2 et l'envoi de données de fichier et de données multiparties est totalement génial) - cela montre le sucre syntaxique pour l'envoi de XHR avec JavaScript - vous pourriez vouloir mettre cela dans un article de blog (j'aimerais bien) ou même dans une bibliothèque (je ne suis pas sûr du nom). x , ajax o xhr pourrait être plus agréable :)). Je ne vois pas comment cela permet de renvoyer la réponse d'un appel AJAX. (quelqu'un pourrait toujours faire var res = x("url") et ne pas comprendre pourquoi ça ne marche pas ;)). D'ailleurs, ce serait cool si vous renvoyez c de la méthode afin que les utilisateurs puissent s'accrocher à error etc.

33 votes

2.ajax is meant to be async.. so NO var res=x('url').. C'est tout l'intérêt de cette question et des réponses :)

4 votes

Pourquoi y a-t-il un paramètre 'c' dans les fonctions, si sur la première ligne vous écrasez la valeur qu'il avait ? ai-je manqué quelque chose ?

290voto

Nic Points 187

Vous utilisez Ajax de manière incorrecte. L'idée est de ne rien renvoyer, mais de transmettre les données à ce que l'on appelle une fonction de rappel, qui traite les données.

IE :

function handleData( responseData ) {
    // do what you want with the data
    console.log(responseData);
}

$.ajax({
    url: "hi.php",
    ...
    success: function ( data, status, XHR ) {
        handleData(data);
    }
});

Le fait de renvoyer quoi que ce soit dans le gestionnaire de soumission n'aura aucun effet, vous devez au contraire soit transmettre les données, soit en faire ce que vous voulez directement dans la fonction de réussite.

21 votes

Cette réponse est complètement sémantique... votre méthode de réussite est juste un callback dans un callback. Vous pourriez simplement avoir success: handleData et ça marcherait.

7 votes

Et si vous voulez retourner la "responseData" en dehors de "handleData" ... :) ... comment allez-vous faire ... ? ... parce qu'un simple retour le renverra au callback "success" de l'ajax ... et non en dehors de "handleData" ...

0 votes

@Jacques & @pesho hristov Vous avez manqué ce point. Le gestionnaire de soumission n'est pas le success c'est la portée environnante de la méthode $.ajax .

266voto

Hemant Bavle Points 182

La solution la plus simple est de créer une fonction Javascript et de l'appeler pour le rappel du succès d'ajax.

  function callServerAsync(){
   $.ajax({
        url: '...',
        success: function(response) {
            successCallback(response);

        }
    });
  }

  function successCallback(responseObj){
     //do something like read the response and show data 
     alert(JSON.stringify(responseObj)); // Only applicable to JSON response
   }

11 votes

Je ne sais pas qui a voté négativement. Mais c'est un contournement qui a fonctionné, en fait j'ai utilisé cette approche pour créer une application entière. Le jquery.ajax ne renvoie pas de données, il est donc préférable d'utiliser l'approche ci-dessus. Si c'est faux, veuillez expliquer et suggérer une meilleure façon de le faire.

20 votes

Désolé, j'ai oublié de laisser un commentaire (je le fais d'habitude !). J'ai mis une décote. Les notes négatives n'indiquent pas l'exactitude des faits ou leur absence, mais l'utilité dans le contexte ou leur absence. Je ne trouve pas votre réponse utile compte tenu de celle de Félix qui l'explique déjà mais de manière beaucoup plus détaillée. D'ailleurs, pourquoi stringifier la réponse si elle est en JSON ?

11 votes

Ok.. @Benjamin j'ai utilisé stringify, pour convertir un objet JSON en chaîne. Et merci d'avoir clarifié votre point de vue. Je garderai à l'esprit de poster des réponses plus élaborées.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X