2010-07-13 9 views
0

Je veux un peu de javascript + ajax pour vérifier la disponibilité du nom d'utilisateur à la volée. Et j'ai quelques problèmes ...Vérifiez la disponibilité du nom d'utilisateur à la volée?

Imaginons la situation lorsque nous vérifions la disponibilité du nom d'utilisateur sur l'événement de flou.

si nous obtenons tel scénario ...

  • a) l'utilisateur est entré le nom d'utilisateur "kir"
  • b) se concentre sur un autre élément
  • c) demande ajax a commencé (demander la disponibilité de « kir » nom d'utilisateur)
  • d) l'utilisateur se concentre sur le nom d'utilisateur et tapez une lettre « kira » (réponse c) est reçu pas encore)
  • e) se concentre sur un autre élément
  • f) requête ajax démarrée (demandant la disponibilité du nom d'utilisateur "kirA")
  • g) nous obtenons la réponse de c) et telling user that username is available, but it not (because we're telling about "kir", but not "kirA").

Que dois-je faire pour éviter une telle situation? Utilisez-vous une sorte de jetons générés aléatoirement pour vérifier la validité de la réponse?

Merci

Répondre

5

Vous avez besoin d'une sorte de correspondance entre l'objet de requête XHR et la requête de nom d'utilisateur qu'il contenait. Ou dans la réponse du serveur à la requête AJAX, incluez également le nom d'utilisateur. Une réponse peut ressembler à:

{ 
    username: "kir", 
    available: false 
} 

Dans le rappel, vérifiez si la valeur actuelle est la même zone de texte comme le nom d'utilisateur retourné. Si oui, alors montrez l'erreur, sinon ignorez simplement cette réponse.

+0

Excellente solution! – Kirzilla

+0

http://stackoverflow.com/questions/3235517/check-username-availability-on-fly/3235551#3235551 est de loin meilleur. rien d'autre ne sera envoyé/reçu du serveur - tout est fait sur le client –

+0

@Andreas - Pour moi, il ne semble pas que l'ajout du nom d'utilisateur surcharge la réponse, mais plutôt une réponse complète à la place. De même, dans une requête de saisie semi-automatique, l'inclusion de la requête dans la réponse est un modèle commun et quelques octets supplémentaires ne sont généralement pas considérés comme une charge importante à moins que vous ne travailliez à l'échelle de Google. – Anurag

0

Vous pouvez désactiver l'entrée alors que la ajax est en cours.

+6

Ce serait une mauvaise solution en termes de facilité d'utilisation. Facile sur le code, oui. – Anurag

+0

Eh bien, à en juger par l'OP, "Easy on the code" serait un excellent premier pas. – zaf

3

vous avez juste besoin de la bonne portée de la variable de demande asynchrone!
Si vous créez une nouvelle requête, vérifiez s'il y en a déjà une, si oui: définissez-la sur null/annulez-la, et continuez!

une autre variante serait la suivante: bloc ui, charger une fileuse-icône, bloquer l'entrée, ... (pas que les solutions de belles ...)

modifier:
Je pense ajax/... est une bonne chose, mais quand il s'agit d'ajouter de plus en plus de propriétés à une demande, vous devriez être prudent. encore plus quand vous pouvez trouver une solution plus agréable (et vous n'avez pas besoin d'une interaction ui explicite comme userA is not available)

+1

Exemple à http://stackoverflow.com/questions/446594/kill-ajax-requests-using-javascript-using-jquery – Nick

+0

@Nick: nice :)! –

5

Vous devriez le XHR lorsque vous en créez un nouveau.

var ongoingRequest = null; 

function test() { 
    if(ongoingRequest != null) { 
     ongoingRequest.abort(); 
    } 

    ongoingRequest = $.ajax(...); 
} 

Vous pouvez ajouter des fonctionnalités supplémentaires pour valider une fois de plus quand vous obtenez la réponse:

$.ajax({ 
    ... 
    data: { query: query }, 
    success: (function(q) { 
     return function(result) { 
      if($('#myTxt').val() != q) { 
      // the textbox value is not the same as the query was 
      // at the time of creating this response! 
      return false; 
      } 

      ... 
     } 
    })(query) 
}); 
+1

ahh ... votre montage est vraiment sympa! mettre en cache la valeur de la zone de texte sur le client et ne pas le transmettre ... oui ... j'aurais pu trouver cela :) –

+1

+1 La réponse la plus douce ici. – zaf

0

Ou, vous pouvez le faire « g) nous obtenons de réponse c) et l'utilisateur indiquant que le nom d'utilisateur kir n'est pas disponible »

1

Voici ce que j'utilise à cette fin:

JAVASCRIPT:

$(document).ready(function() { 
    $("#username").blur(function() { 
     //remove all the class add the messagebox classes and start fading 
     $("#username_status").removeClass().addClass('username_status').text('Checking username').fadeIn("slow"); 
     //verify entered username 
     $.post("path to php file",{ user_name:$(this).val() } ,function(data) { 
      // username not avaiable 
      if (data=='no') { 
       $("#username_status").fadeTo(200,0.1,function() { 
        $(this).html('Username in use').addClass('username_status_error').fadeTo(900,1); 
       }); 
      // username available 
      }else if (data=='yes') { 
       $("#username_status").fadeTo(200,0.1,function() { 
        $(this).html('username available').addClass('username_status_ok').fadeTo(900,1); 
       }); 
      // username field empty 
      }else if (data=='empty') { 
       $("#username_status").fadeTo(200,0.1,function() { 
        $(this).html('username field is empty').addClass('username_status_error').fadeTo(900,1); 
       }); 
      // username check error 
      }else{ 
       $("#username_status").fadeTo(200,0.1,function() { 
        $(this).html('fail to check username').addClass('username_status_error').fadeTo(900,1); 
       }); 
      } 
     }); 
    }); 
}); 

PHP FICHIER DE POST avec AJAX:

<?php 
    require_once ('db_connect.php'); // include the database connection 
    if ($_POST['user_name']!="") { 
     // check if username is available from login table 
     $query = sprintf(" select * from login where username = '%s' ", mysql_real_escape_string($_POST['user_name'])); 
     if (mysql_query($query)) { 
      if (mysql_num_rows(mysql_query($query))>0) { 
       echo "no"; 
      }else{ 
       echo "yes"; 
      } 
     }else{ 
      echo "error"; 
     } 
    }else{ 
     echo "empty"; 
    } 
?> 

ET HTML FORMULAIRE:

<form name="login-form" id="login-form" class="clients_form" method="post" action="form post link"> 
    <ol> 
    <li> 
     <label for="login_usr" class="OF_name">Username:<span class="mandatory">*</span><br></label> 
     <input tabindex="1" accesskey="u" name="username" type="text" maxlength="30" id="username"> 
    </li> 
    <li> 
     <label for="login_pwd" class="OF_email">Password:<span class="mandatory">*</span><br></label> 
     <input tabindex="2" accesskey="p" name="password" type="password" maxlength="15" id="password"> 
    </li> 
    <li class="buttons"> 
     <input class="btn" tabindex="3" accesskey="l" type="submit" name="cmdlogin" value="Login"> 
     <input class="btn" name="cancel" type="button" value="Cancel" onclick="location.href='cancel link'"> 
    </li> 
    </ol> 
    <br><br><br> 
</form> 

Ceci est un exemple simple que je l'ai créé pour vous montrer, mais devrait fonctionner très bien ...

Lorsque l'utilisateur quitte le nom d'utilisateur domaine, l'AJAX publiera le fichier PHP pour vérifier la base de données, si l'utilisateur retourne au champ de l'utilisateur, encore une fois, wend it laisse, Ajax postera.

Espérons que cela aide!

+0

putain .. jamais vu une solution générique plus spécifique ...:( –

+0

Cela ne résout pas le problème de plusieurs demandes subséquentes et obtenir leurs réponses dans un ordre asynchrone, ce qui est toute la question à propos.En outre, vous n'avez pas vraiment besoin de publier la valeur sur votre serveur pour vérifier si elle est une chaîne vide =) –

+0

il doit, s'il veut être un mec défensif! n'importe qui pourrait exécuter son script et faire une injection ... –

0

La première suggestion d'Anurag (conserver les données de requête avec la requête) est plus optimale pour le cas général qui renvoie le nom d'utilisateur. Si vous envoyez plusieurs paramètres longs, vous ne voulez pas qu'ils utilisent inutilement votre bande passante et augmentent le temps de réponse.

exemple rapide, en gardant la trace de ce que vous envoyez:

function checkUserName(){ 
    var uName=$('#uname').val(); // get it immediately stored into the variable 
    $.ajax({url: '...', data: {username: uName}, success: function(data){ 
     if(data.is_available) 
      alert(uName + " is available."); // this instance of the variable is still in scope, even the checkUserName function has been re-called since 
    }); 
} 

Ce code peut encore être optimisé, mais vous voyez l'idée. Si vous utilisez ce genre de chose souvent, vous devriez lire sur la portée en javascript (fermetures, etc).

Questions connexes