From 74167f302c314bde17b54bff9e8b65e21dfc8cf1 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Oct 2011 16:25:57 +0200 Subject: [PATCH 1/3] =?UTF-8?q?Post=20sur=20les=20subtilit=E9s=20du=20logi?= =?UTF-8?q?n=20en=20javascript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _posts/2011-10-19-subtilite-du-login.markdown | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 _posts/2011-10-19-subtilite-du-login.markdown diff --git a/_posts/2011-10-19-subtilite-du-login.markdown b/_posts/2011-10-19-subtilite-du-login.markdown new file mode 100644 index 0000000..d0cac38 --- /dev/null +++ b/_posts/2011-10-19-subtilite-du-login.markdown @@ -0,0 +1,149 @@ +--- +layout: post +title: Les subtilité des formulaire de login en JS +author: feugy +tags: [javascript, login, formulaire, chrome, firefox] +published: false +--- + +Quoi de plus simple qu'un formulaire de login ? +En HTML, certes, mais lorsque qu'on parle d'application riche en javascript, c'est une autre histoire. + +Si vous ne comprenez pas pourquoi le navigateur ne retient pas vos logins, ne propose pas le mot de passe associé, ou ne réagit pas à la touche entrée, lisez la suite ! + +Cet article est le résultat de **l'étude empirique du comportement des navigateurs**. +Il est donc sujet à caution: tout dépends de votre navigateur, et de sa version. +J'espère simplement vous aider à comprendre et éviter les principaux chausse-trappes, sans avoir recours à l'installation d'un plugin :) + + +## Mais ce n'est qu'un formulaire ! + +Hélas non... Les formulaire de login (un champs text + un champ password) sont détecté par le navigateur, qui va traiter différemment des autres champs textuels. + +C'est là le premier problème : +>**Le formulaire doit être présent dans le DOM au chargement de la page.** + +Oui, vous avez compris : si vous construisez votre formulaire directement en JS, ou si vous utilisez un template que vous accrochez une fois la page chargée, votre formulaire ne sera ignorés par certains navigateurs. + +L'astuce que j'utilise consiste a : + +* inclure le formulaire de login dans ma page index.html +* le masquer avec un style CSS display:none. +* le déplacer par la suite en javascript là où il doit apparaitre dans le rendu + +**index.html** + + + +**login.js** + + $('.loginContainer', this.element).append($('#loginStock > *')); + + +## Dois-je mettre un champ de type submit ? + +S'il n'y a que les champs de type text et password, le navigateur ne retiendra pas le mot de passe. + +>**Le champ de type submit est indispensable.** + +Même s'il est masqué (le bouton n'est pas encore bien skinnable, même en CSS 3), il doit être présent. + +**index.html** + + + +**login.js** + + $('.loginContainer .submit').click(function(event){ + // Déclenche la soumission du formulaire. + $('#formLogin').submit(); + // Annule la propagation du Click sur le lien, pas de la soumission du formulaire ! + return false; + }).button({label:'log in !'}); + + +## Doit-on stopper la propagation de l'évènement submit ? + +Le problème se pose si vous ne réalisez pas de "vrai" POST lorsque l'utilisateur déclenche la soumission du formulaire. +Dans la majorité des applications riches, l'authentification se fait via une Api, et donc un appel Ajax. + +On se branche alors sur l'évènement submit, et on annule sa propagation. Par exemple : + +Seulement, en stoppant l'évènement de soumission, le navigateur ne retient pas le login et le mot de passe. + +>**Pour que le navigateur mémorise le couple login/mot de passe, l'évènement submit doit se propager.** + +Cela implique: + +* Que le formulaire pointe sur une véritable url, sinon, une vilaine 404 apparaitra dans votre console +* Que le résultat de la soumission est routée dans une iframe (désolé pour les puristes :)), sans quoi, toute la page se rechargera + +Donc généralement, mon service web propose une Api POST qui ne fait rien et renvoi une page vide, et j'utilise une iframe masquée. + +**index.html** + + + + +**login.js** + + $('#formLogin').submit(function(event){ + // Ici mon appel ajax, et surtout, ne pas renvoyer false ni n'invoquer event.stopPropagation(). + }); + + +### Une petite astuce : lorsque l'authentification échoue. + +A partir du moment où l'évènement submit est propagé, et qu'une réponse HTTP est reçue, le navigateur conservera bien le mot de passe et le login. + +Mais nous pouvons tirer parti de se comportement, lorsque l'authentification échoue, par exemple si l'utilisateur est inconnu, ou le mot de passe erroné. + +Ainsi, mon appel Ajax est toujours **synchrone** (parfois ça sert !), et s'il échoue, alors dans ce cas, j'annule la propagation de l'évènement submit pour ne pas conserver les mauvais identifiants. + + + +## La touche entrée ne soumet pas toujours mon formulaire... + +Hélas oui, c'est un comportement étrange de certains navigateurs : un formulaire sera automatiquement soumit si on appuie sur entrée dans un de ses champs, sauf s'il à plus d'un champ text/password! + +Nous n'avons donc pas d'autres choix que de gérer nous même en javascript la touche entrée : + +**login.js** + + $('#formLogin input').keyup(function(event){ + if (event.which == '13' && !event.metaKey) { + $('#formLogin').submit(); + // Annule la propagation de l'évènement clavier, pour ne pas soumettre 2 fois le formulaire sur les navigateurs qui supportent correctement la feature. + return false; + } + }); + + +## Conclusion + +Vous voyez ? quand je vous disais que ce n'était pas trivial... + +Mais maintenant, vous avez toutes les clefs pour faire des formulaires qui exploitent le cache de login/mot de passe des navigateurs. + +Espérons que dans un futur proche, les navigateurs harmonisent un peu plus leur fonctionnement, de manière à éviter tout ces tricks... + +Damien. \ No newline at end of file From 850e96cb4c0f7781702a6f0357b89f8671cc5cfa Mon Sep 17 00:00:00 2001 From: feugy Date: Wed, 19 Oct 2011 17:28:10 +0300 Subject: [PATCH 2/3] Update _posts/2011-10-19-subtilite-du-login.markdown --- _posts/2011-10-19-subtilite-du-login.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/2011-10-19-subtilite-du-login.markdown b/_posts/2011-10-19-subtilite-du-login.markdown index d0cac38..67ae3bd 100644 --- a/_posts/2011-10-19-subtilite-du-login.markdown +++ b/_posts/2011-10-19-subtilite-du-login.markdown @@ -2,7 +2,7 @@ layout: post title: Les subtilité des formulaire de login en JS author: feugy -tags: [javascript, login, formulaire, chrome, firefox] +tags: [javascript, login, formulaire, chrome, firefox, jQuery] published: false --- From dc780d9c9aa62340c30e416fbe18df5dfaf98e85 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 20 Oct 2011 10:03:09 +0200 Subject: [PATCH 3/3] Nouvelle version du post sur le login en js --- ...> 2011-10-19-subtilites-du-login.markdown} | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 deletions(-) rename _posts/{2011-10-19-subtilite-du-login.markdown => 2011-10-19-subtilites-du-login.markdown} (65%) diff --git a/_posts/2011-10-19-subtilite-du-login.markdown b/_posts/2011-10-19-subtilites-du-login.markdown similarity index 65% rename from _posts/2011-10-19-subtilite-du-login.markdown rename to _posts/2011-10-19-subtilites-du-login.markdown index d0cac38..3a589e8 100644 --- a/_posts/2011-10-19-subtilite-du-login.markdown +++ b/_posts/2011-10-19-subtilites-du-login.markdown @@ -1,8 +1,8 @@ --- layout: post -title: Les subtilité des formulaire de login en JS +title: Les subtilités des formulaires de login en JS author: feugy -tags: [javascript, login, formulaire, chrome, firefox] +tags: [javascript, login, formulaire, chrome, firefox, jQuery] published: false --- @@ -12,20 +12,20 @@ En HTML, certes, mais lorsque qu'on parle d'application riche en javascript, c'e Si vous ne comprenez pas pourquoi le navigateur ne retient pas vos logins, ne propose pas le mot de passe associé, ou ne réagit pas à la touche entrée, lisez la suite ! Cet article est le résultat de **l'étude empirique du comportement des navigateurs**. -Il est donc sujet à caution: tout dépends de votre navigateur, et de sa version. +Il est donc sujet à caution: tout dépends de votre navigateur et de sa version. J'espère simplement vous aider à comprendre et éviter les principaux chausse-trappes, sans avoir recours à l'installation d'un plugin :) ## Mais ce n'est qu'un formulaire ! -Hélas non... Les formulaire de login (un champs text + un champ password) sont détecté par le navigateur, qui va traiter différemment des autres champs textuels. +Hélas non... Les formulaires de login (un champs text + un champ password) sont détectés par le navigateur, qui va les traiter différemment des autres champs textuels. C'est là le premier problème : >**Le formulaire doit être présent dans le DOM au chargement de la page.** -Oui, vous avez compris : si vous construisez votre formulaire directement en JS, ou si vous utilisez un template que vous accrochez une fois la page chargée, votre formulaire ne sera ignorés par certains navigateurs. +Oui, vous avez compris : si vous construisez votre formulaire directement en JS, ou si vous utilisez un template que vous accrochez une fois la page chargée, votre formulaire sera ignoré par certains navigateurs. -L'astuce que j'utilise consiste a : +L'astuce que j'utilise consiste à: * inclure le formulaire de login dans ma page index.html * le masquer avec un style CSS display:none. @@ -74,23 +74,23 @@ Même s'il est masqué (le bouton n'est pas encore bien skinnable, même en CSS }).button({label:'log in !'}); -## Doit-on stopper la propagation de l'évènement submit ? +## Doit-on stopper la propagation de l'événement submit ? -Le problème se pose si vous ne réalisez pas de "vrai" POST lorsque l'utilisateur déclenche la soumission du formulaire. -Dans la majorité des applications riches, l'authentification se fait via une Api, et donc un appel Ajax. +Le problème se pose si vous ne réalisez pas un "vrai" POST lorsque l'utilisateur déclenche la soumission du formulaire. +Dans la majorité des applications riches, l'authentification se fait via une API, et donc un appel Ajax. -On se branche alors sur l'évènement submit, et on annule sa propagation. Par exemple : +On se branche alors sur l'événement submit, et on annule sa propagation. -Seulement, en stoppant l'évènement de soumission, le navigateur ne retient pas le login et le mot de passe. +Seulement, en stoppant l'événement de soumission, le navigateur ne retient pas le login et le mot de passe. ->**Pour que le navigateur mémorise le couple login/mot de passe, l'évènement submit doit se propager.** +>**Pour que le navigateur mémorise le couple login/mot de passe, l'événement submit doit se propager.** Cela implique: -* Que le formulaire pointe sur une véritable url, sinon, une vilaine 404 apparaitra dans votre console -* Que le résultat de la soumission est routée dans une iframe (désolé pour les puristes :)), sans quoi, toute la page se rechargera +* que le formulaire pointe sur une véritable url, sinon, une vilaine 404 apparaitra dans votre console +* que le résultat de la soumission soit routée dans une iframe (désolé pour les puristes :)), sans quoi, toute la page se rechargera -Donc généralement, mon service web propose une Api POST qui ne fait rien et renvoi une page vide, et j'utilise une iframe masquée. +Donc généralement, mon service web propose une API POST qui ne fait rien et renvoie une page vide, et j'utilise une iframe masquée. **index.html** @@ -107,35 +107,37 @@ Donc généralement, mon service web propose une Api POST qui ne fait rien et re **login.js** $('#formLogin').submit(function(event){ - // Ici mon appel ajax, et surtout, ne pas renvoyer false ni n'invoquer event.stopPropagation(). + // Ici mon appel ajax, et surtout, ne pas renvoyer false ni invoquer event.stopPropagation(). }); ### Une petite astuce : lorsque l'authentification échoue. -A partir du moment où l'évènement submit est propagé, et qu'une réponse HTTP est reçue, le navigateur conservera bien le mot de passe et le login. +A partir du moment où l'événement submit est propagé, et qu'une réponse HTTP est reçue, le navigateur conservera bien le mot de passe et le login. -Mais nous pouvons tirer parti de se comportement, lorsque l'authentification échoue, par exemple si l'utilisateur est inconnu, ou le mot de passe erroné. +Mais nous pouvons tirer parti de ce comportement, lorsque l'authentification échoue, par exemple si l'utilisateur est inconnu, ou le mot de passe erroné. -Ainsi, mon appel Ajax est toujours **synchrone** (parfois ça sert !), et s'il échoue, alors dans ce cas, j'annule la propagation de l'évènement submit pour ne pas conserver les mauvais identifiants. +Ainsi, mon appel Ajax est toujours **synchrone** (parfois ça sert !), et s'il échoue, alors dans ce cas, j'annule la propagation de l'événement submit pour ne pas conserver les mauvais identifiants. ## La touche entrée ne soumet pas toujours mon formulaire... -Hélas oui, c'est un comportement étrange de certains navigateurs : un formulaire sera automatiquement soumit si on appuie sur entrée dans un de ses champs, sauf s'il à plus d'un champ text/password! +Hélas oui, c'est un comportement étrange de certains navigateurs : un formulaire sera automatiquement soumit si on appuie sur entrée dans un de ses champs, sauf si le bouton submit est invisible ! -Nous n'avons donc pas d'autres choix que de gérer nous même en javascript la touche entrée : +Donc il faut eviter le display:none ou le visibility:hidden sur le champ. +Personnellement, je lui affecte une taille de zéro. Vous pouvez aussi le positionner en absolu, en dehors de la zone visible, ou le mettre en dessous d'un autre élément avec le z-index -**login.js** +**index.html** - $('#formLogin input').keyup(function(event){ - if (event.which == '13' && !event.metaKey) { - $('#formLogin').submit(); - // Annule la propagation de l'évènement clavier, pour ne pas soumettre 2 fois le formulaire sur les navigateurs qui supportent correctement la feature. - return false; - } - }); + ## Conclusion