58 votes

jquery n'appelle pas au succès de la méthode $.ajax pour les rails standard RESTE SUPPRIMER la réponse

Peut-être un tel problème n'est pas nouveau, mais je n'ai rien trouvé de similaire. J'ai comme jQuery code:

$.ajax({ 
  url : ('/people/'+id), 
  type : 'DELETE', 
  dataType : 'json', 
  success : function(e) {
    table.getItems(currentPage);
  }
});

Mon Rails contrôleur ressemble à ceci:

def destroy
    @person = Person.find(params[:id])
    @person.destroy

    respond_to do |format|
      format.html { redirect_to(people_url) }
      format.json  { render :json => @person, :status => :ok }
    end
end

C'est le travail.

Mais quand j'utilise la suite (comme généré par le standard), l' success de rappel n'est pas appelée:

def destroy
    @person = Person.find(params[:id])
    @person.destroy

    respond_to do |format|
      format.html { redirect_to(people_url) }
      format.json  { head :ok }
    end
end

Testé sous rails 3.0.3, jQuery 1.4.2 et Firefox 3.6.13.
Firebug dit, que la requête est tiré et renvoie 200 OK dans les deux cas, l'élément est supprimé dans les deux cas trop. Mais dans le second cas, le rappel n'est pas appelé.

Est-il une différence significative dans le REPOS, et est-il un moyen d'utiliser jQuery en utilisant le scaffolding contrôleur?

73voto

Mike Johnson Points 663

J'ai rencontré quelques fois et la réponse est d'une simplicité trompeuse.

Vous utilisez dataType : 'json' de votre $.appel ajax, donc jQuery attend une réponse JSON. Pour des raisons qui échappent à toute personne qui est sain d'esprit, une réponse vide est considéré comme non valide JSON par l'analyseur.

Donc, si vous vous attendez vraiment à obtenir soit une erreur ou d'un nu-200 OK en-tête, il suffit de mettre dataType : 'html' dans votre demande et cela devrait fonctionner (si vous ne définissez pas de type de données, jQuery va essayer de deviner de quel type est basé sur les en-têtes de réponse, etc., et pouvait encore deviner json, dans ce cas, vous souhaitez toujours avoir ce problème). Si vous vous attendez à obtenir JSON en arrière parfois, au lieu d'utiliser head :ok utiliser quelque chose comme render :json => "we good!", :status => :ok

6voto

Neil Sarkar Points 1584

GearHead est correct, sauf que le jQuery analyseur est en fait assez intelligent maintenant pour traiter une chaîne vide de réponse nulle et de ne pas tenter de l'analyser.

Toutefois, si vous avez des appels qui reçoivent parfois json et reçoivent parfois un head réponse, et vous n'avez pas accès au serveur ou ne veulent pas en changer tous vos head des appels, vous pouvez le faire, une solution alternative:

Le problème est que les Rails envoie un espace unique dans une réponse vide lorsque vous utilisez head (voir ici: Comment retourner vraiment vide de corps dans les rails? c'est à dire le contenu de longueur 0)

Les parties pertinentes de l'jQuery parseJSON fonction ressembler à ceci au moment d'écrire ces lignes:

parseJSON: function( data ) {
    if ( typeof data !== "string" || !data ) {
        return null;
    }

    // Make sure leading/trailing whitespace is removed (IE can't handle it)
    data = jQuery.trim( data );

    // Attempt to parse using the native JSON parser first
    if ( window.JSON && window.JSON.parse ) {
        return window.JSON.parse( data );
    }

Comme vous pouvez le voir, jQuery est de tester si les données est une chaîne vide avant la coupe. Il essaie ensuite d' JSON.parse("") que vous pouvez voir dans votre console une erreur, le déclenchement de l'ajax d'erreur de rappel via un catch déclaration.

Il y a une solution simple. jQuery permet d'utiliser des convertisseurs quand un type de données est demandée et un autre est retourné. Voir ici pour plus de détails: http://api.jquery.com/extending-ajax/

Depuis les rails head réponse rendu sous la forme de texte, vous pouvez simplement définir un texte json convertisseur qui limitera la réponse avant de tenter de l'analyser. Il suffit d'ajouter ce fragment:

// deal with rails ' ' empty response
jQuery.ajaxSetup({
  converters: {
    "text json": function (response) {
      jQuery.parseJSON($.trim(response))
    }
  }
})

0voto

C'est parfois causée par une ancienne version de jQuery Valider Plugin. Si vous utilisez ce plugin, ce qui conduit parfois à cette question. Il y a une mise à jour qui résout ce, si elle s'applique à votre cas.

Alternativement, vous pouvez probablement comprendre ce qui ne va pas par la mise en place d'un gestionnaire d'erreur par:

$.ajaxSetup() ou $.ajaxError()

Ce sera probablement retourner une erreur d'analyse. Les nouvelles versions de jQuery sont connus pour être très strict en ce qui concerne JSON de l'analyse.

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