Je voudrais obtenir la valeur appropriée pour Je veux que la fonction Ajax met à jour ma variable OkLogin sur FALSE, une inadéquation accessible. P> oklogin code> lorsque l'utilisateur est incorrect et arrêtez le formulaire d'aller de l'avant, mais j'ai remarqué que lorsque j'appelle la fonction est exécutée en premier lieu. que l'appel AJAX, qui devrait être en arrière.
<form action="test.html" onsubmit="return loginProcess();">
<label for="usernameLogin" class="col-sm-4 col-form-label">Username</label>
<input class="form-control" type="text" id="usernameLogin" required>
<label for="passwordLogin" class="col-sm-4 col-form-label">Password</label>
<input class="form-control" type="password" id="passwordLogin" required>
<input type="submit" class="btn btn-primary btn-block" id="loginSubmitBtn" value="Login">
</form>
<script>
function loginProcess() {
let users, usernameLogin, passwordLogin;
let ajaxCall = new XMLHttpRequest();
let okLogin = true;
usernameLogin = document.getElementById("usernameLogin").value;
passwordLogin = document.getElementById("passwordLogin").value;
ajaxCall.onreadystatechange = function() {
if (ajaxCall.readyState == 4 && ajaxCall.status == 200) {
users = JSON.parse(ajaxCall.responseText);
for (let item in users) {
if (item === "username") {
if (usernameLogin !== users["username"]) {
okLogin = false;
}
console.log("Username: " + okLogin);
}
if (item === "password") {
if (passwordLogin !== users["password"]) {
okLogin = false;
}
}
}
}
}
ajaxCall.open("GET", "docs/users.json", true);
ajaxCall.send();
return okLogin;
}
</script>
3 Réponses :
Cela ne fonctionnera pas car les demandes AJAX sont asynchrones. En d'autres termes, le code dans Je remarquerais également que l'authentification est une chose importante à avoir raison, et je pense que vous feriez bien de regarder quelques exemples d'une authentification correcte. De l'apparence de celui-ci, vous retournez une liste de tous les noms d'utilisateur et mots de passe en clairexuant dans l'appel. C'est un design très insécurisé. Si vous avez des intentions d'utilisation de cela pour autre chose qu'une expérience, vous ne devriez pas faire les choses de cette façon. En fait, même si vous n'utilisez que cela comme une expérience, je suggérerais d'essayer de faire une manière différente pour obtenir l'expérience de faire des choses comment elles devraient être faites. P> En tout cas, la manière de rendre ce travail tel quel serait, au lieu de revenir, prenez des mesures dans le rappel. Ce n'est pas clair dans le code que vous avez soumis exactement ce qui se produira lorsque la méthode code> loginprocess code> (de l'apparence ne se passe rien. Vous pouvez peut-être appeler une autre méthode avec votre fonction Exemple: P> onreadyStatechange code> n'est défini que pour être exécuté plus tard, une fois que l'appel AJAX est revenu. C'est pourquoi votre méthode est renvoyée avant la fin de l'appel AJAX.
OnReadyStatechange CODE> avec une fonction vraie ou false, et laissez cette fonction gérer ce qui devrait se produire en fonction d'une connexion réussie ou infructueuse. P>
ajaxCall.onreadystatechange = function() {
if (ajaxCall.readyState == 4 && ajaxCall.status == 200) {
[your code to check the login here]
someOtherFunction(okLogin)
}
}
Merci beaucoup pour la recommandation. J'ai fait des exemples de départ ce mois-ci, mais je ne comprends pas comment cela fonctionne, j'ai fait beaucoup d'exemples, mais cela semble étrange et compliqué, est-ce une meilleure façon de faire cela? Je ne suis pas un programmeur professionnel, je n'ai donc pas d'expérience dans la sécurité des connexions et des moyens modernes de récupérer des données.
Bienvenue à. Votre problème est dû à la nature du JavaScript asynchrone. Votre XMLHTTPQUEST prend un certain temps pour obtenir une réponse. À cause de cela, vous devez attendre avant de retourner une valeur jusqu'à ce que la demande soit terminée. Vous retournerez maintenant instantanément Donc, vous devez retarder cela. Vous pouvez utiliser au lieu du Maintenant avec async / attendre, vous pouvez rendre votre fonction asynchrone, ce qui signifie que cela prendra du temps à complète, mais faire autre chose quand c'est fait. Le mot clé code> attendre code> peut être mis à l'avant de toute fonction de retour de la promesse, comme Fetch, de attendre em> la fonction pour terminer et obtenir la valeur de celle-ci. P> Dans votre code, cela ressemblerait à ceci. P> oklogin code> sans la demande de la modifier.
async code> /
attendre code> pour attendre la demande de finition et continuez avec votre processus. Tout est basé sur promet , un objet qui peut chaîner des rappels avec le
alors code> méthode. p>
XMLHTTPQUEST code> constructeur, essayez le
Fetch API code>
. C'est une version plus moderne du même principe, mais avec un flux de travail plus simple et plus puissant et cela fonctionne avec des promesses. P> loginProcess().then((loginStatus) => {
console.log(loginStatus)
});
Vous avez dit que je peux essayer d'utiliser Fetch ou Async / Attendre, mais lequel des deux devrais-je utiliser? Ont-ils une différence? Parce que vous avez utilisé Async / attendre ici, même si vous avez dit que Fetch était le meilleur à utiliser. Je voudrais donc en savoir plus à ce sujet et merci beaucoup! Et avons-je écrit le deuxième code? Celui avec le "alors" et la console?
Utilise les deux. Fetch est un substitut de XMLHTTPRequest et retournera une promesse quand elle est appelée. Avec async / attendre, vous pouvez attendre la récupération de résoudre code> (finition) et stocker la valeur qu'elle revient. Sans async / attendre, vous devriez compter sur la méthode
code>, qui est une sorte de la même chose mais fonctionne différemment. La deuxième partie avec le
puis code> et
console code> doit être dans votre gestionnaire de soumission.
Ah Okey, qu'entendez-vous par "Soumettre le gestionnaire"?
Comme écrit, votre code reviendra toujours vrai; La valeur de Une solution serait de rendre l'appel AJAX synchrone, en passant Je suggérerais ceci approche: changez ceci ... p> ... à ceci: p> En d'autres termes, lorsque l'utilisateur Soume le formulaire, appelez Maintenant, notre stratégie sera de faire votre rappel (votre Vous pouvez également utiliser des promesses ( Note finale: Vous pouvez également utiliser espère que cela aide! p> p> oklogin code>, que vous définissez pour être vraie, ne sera jamais autre chose que cela. C'est parce que
ajaxcall.send () code> est asynchrone: il commence l'appel Ajax, mais c'est tout; Cela n'attend pas que l'appel réussisse (ou échoue). Donc, la prochaine chose qui se passe, chaque fois que vous appelez
ajaxcall.send () code>, est-ce que vous retournez la valeur actuelle de
oklogin code>, qui sera vrai à chaque fois, car Tout code qui pourrait changer sa valeur n'aura pas encore été exécuté. (Il ne sera exécuté qu'après une réponse à votre demande Ajax.) J'espère que cela a du sens; Ceci est une erreur courante lors de la gestion des méthodes telles que
envoyer () code> qui sont asynchrones em> - que commencent em> quelque chose (dans ce cas une demande AJAX) mais N'attendez pas qu'il finit avant de revenir. (Et dans votre cas, retournez une valeur qui sera vraie à chaque fois, car chaque fois, le code de votre
ajaxcall.onreadytstatechange code> sera exécuté après em> vous retournerez
Oklogin code>.)
false code> au lieu de
true code> comme dernier argument sur
Ouvrir () code>. Cela fonctionnera, mais c'est une idée grave. Faire des sourcils synchrones sont profondément fronça les sourcils, car il provoque la suspension du navigateur de l'utilisateur jusqu'à ce qu'une réponse soit reçue. Cela pourrait prendre quelques millisecondes (pas un problème) mais si la réponse est lente en arrivant, elle pourrait prendre une seconde (très mauvaise) ou plusieurs secondes (totalement inacceptable). P>
loginprocess () code>, qui commence votre appel AJAX, puis renvoyez FALSE (qui, pour l'instant, gardez le formulaire d'être soumis). Nous allons maintenant ignorer la valeur de retour de
loginprocess () code>; Ce n'est pas pertinent. J'ai également ajouté une classe
code> à votre formulaire, que nous allons utiliser dans une minute. P>
ajaxcall .EnreadyStatechange code> Code), qui sera exécuté après une réponse réussie, soumettez votre formulaire uniquement si
oklogin code> est vrai. Pour ce faire, changez votre code comme suit: p>
alors () code>, etc.) mais c'est probablement un bon Idée de comprendre les rappels avant de vous attaquer à des promesses, si vous essayez de comprendre les concepts asynchrones. P>
async / attendre code> mais avant de le faire, mais avant de le faire, D Voulez comprendre des promesses (et avant ces rappels) - mais plus important,
async / attendre code> ne peut pas être disponible dans tous vos navigateurs cible; Pas, mais non, mais pas les versions de bord précédentes. P>
Merci beaucoup pour cela!! Donc, la fonction reviendra toujours fausse, la seule façon de soumettre quelque chose qui le fait manuellement de l'intérieur de la fonction avec la fonction Soumettre. Parce que cela fonctionne de manière asynchrone, il n'arrive donc pas que la fonction se poursuive, d'accord que j'ai eu. J'ai quelques questions cependant: - À propos de la sécurité ici, que dois-je faire pour que ce soit sécurisé? Ceci n'est qu'un test mini-backend avec JSON, je ne sais pas où commencer. - À propos de "Fetch" et "Async / Attendre", sont-ils les mêmes? Lequel devrais-je utiliser? Lequel est le meilleur pour ce genre de travail?
@JFelya Ceci - développeur.mozilla.org/en-us/docs/ Web / API / FETCH_API traite des différences entre FETCH et XMLHTTPRequest (vous utilisez ce dernier, bien sûr). Fetch est plus récent et plus puissant mais ne fonctionne pas sur certains navigateurs plus âgés. En ce qui concerne ASYNC / AWAIT: Ce n'est pas une alternative à l'une quelconque - c'est une fonction de langue nouvelle qui peut rendre le code asynchrone plus facile à travailler avec (comme des promesses peut). Je suggère d'apprendre d'abord des rappels, puis des promesses, puis asynchrones / attendre (étroitement liées aux promesses). En outre, fonctions génératrices. Mais je m'attaquerais d'abord aux rappels.
@JFelya comme pour la sécurité: vous devez toujours utiliser Post au lieu d'obtenir lors de l'envoi d'informations sensibles. La poste est la valeur par défaut pour XMLHTTPQUEST, mais obtenir est la valeur par défaut pour la soumission d'un formulaire. Donc, vous devriez ajouter méthode = "post" code> à votre
Merci pour cela. J'ai essayé de lire le lien avant pendant un certain temps, mais c'était tellement frustrant que je ne pouvais pas comprendre une chose de cet article, je n'avais rien, désolé, peut-être que c'est ma faute.
Le problème est que vous appelez le
xmlhttprequest code> asynchrone, qui doit être effectué dans votre cas de manière synchrone à la place i> parce que votre
Onsubmit code> aura besoin de quelque chose à retourner ( vrai ou faux) à ce moment-là dans le temps. Essayez de changer cette ligne
ajaxcall.open ("get", "docs / users.json", true); code> to
ajaxcall.open ("get", "docs / users.json", faux); code> et voir ce qui se passe.
@GetSet Cela ne devrait jamais être recommandé car c'est une mauvaise pratique. JavaScript est parfaitement capable de gérer le code ASYNC avec des rappels, des promesses et ASYNC / AWAIT.
@Emielzuurbier, j'ai plus posté mon commentaire car il utilise de près la base de code de l'OP de près, et donc un apprentissage pourrait avoir lieu dans cette approche, tout en clarifiant où l'erreur est. Personnellement, j'irais un itinéraire différent en caché le bouton de soumettre réel à partir d'affichage, puis avec un bouton d'envoi intermédiaire (de
type = "bouton" code>) qui gère tout ordre avant de soumettre le formulaire directement ou via le bouton caché.