Angularjs Dilemme de l'autocomplet Chrome

J'ai un formulaire de connexion simple qui ne fonctionne qu'après avoir utilisé la fonctionnalité complète automatique de Chrome.

Si vous commencez à taper et à utiliser la fonctionnalité d'achèvement automatique et qu'il remplit automatiquement votre mot de passe, mon modèle angularjs n'a pas de valeur pour le mot de passe.

J'ai essayé de désactiver automatiquement le paramètre en définissant l'attribut sur le formulaire autocomplete="off" mais cela ne semble pas avoir d'effet.

Comment puis-je: 1. Assurez-vous que je peux obtenir la valeur si quelqu'un utilise la fonction de remplissage automatique de Chrome? 2. Désactivez la fonctionnalité d'achèvement automatique de Chrome?

 <form class="form-signin" name="form" ng-submit="login()" autocomplete="off"> <h3>Login</h3> <input type="email" name="email" class="form-control" placeholder="Email address" ng-model="user.email" required autofocus> <input type="password" name="password" class="form-control" placeholder="Password" ng-model="user.password" required> <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button> </form> 

À partir du lien ajouté dans le commentaire: https://github.com/angular/angular.js/issues/1460#issuecomment-32491109

 // Due to browsers issue, it's impossible to detect without a timeout any changes of autofilled inputs // https://github.com/angular/angular.js/issues/1460 // https://github.com/angular/angular.js/issues/1460#issuecomment-28662156 // Could break future Angular releases (if use `compile()` instead of `link()) // TODO support select angular.module("app").config(["$provide", function($provide) { var inputDecoration = ["$delegate", "inputsWatcher", function($delegate, inputsWatcher) { var directive = $delegate[0]; var link = directive.link; function linkDecoration(scope, element, attrs, ngModel){ var handler; // By default model.$viewValue is equals to undefined if(attrs.type == "checkbox"){ inputsWatcher.registerInput(handler = function(){ var value = element[0].checked; // By default element is not checked if (value && ngModel.$viewValue !== value) { ngModel.$setViewValue(value); } }); }else if(attrs.type == "radio"){ inputsWatcher.registerInput(handler = function(){ var value = attrs.value; // By default element is not checked if (element[0].checked && ngModel.$viewValue !== value) { ngModel.$setViewValue(value); } }); }else{ inputsWatcher.registerInput(handler = function(){ var value = element.val(); // By default value is an empty string if ((ngModel.$viewValue !== undefined || value !== "") && ngModel.$viewValue !== value) { ngModel.$setViewValue(value); } }); } scope.$on("$destroy", function(){ inputsWatcher.unregisterInput(handler); }); // Exec original `link()` link.apply(this, [].slice.call(arguments, 0)); } // Decorate `link()` don't work for `inputDirective` (why?) /* directive.link = linkDecoration; */ // So use `compile()` instead directive.compile = function compile(element, attrs, transclude){ return linkDecoration; }; delete directive.link; return $delegate; }]; $provide.decorator("inputDirective", inputDecoration); $provide.decorator("textareaDirective", inputDecoration); //TODO decorate selectDirective (see binding "change" for `Single()` and `Multiple()`) }]).factory("inputsWatcher", ["$interval", "$rootScope", function($interval, $rootScope){ var INTERVAL_MS = 500; var promise; var handlers = []; function execHandlers(){ for(var i = 0, l = handlers.length; i < l; i++){ handlers[i](); } } return { registerInput: function registerInput(handler){ if(handlers.push(handler) == 1){ promise = $interval(execHandlers, INTERVAL_MS); } }, unregisterInput: function unregisterInput(handler){ handlers.splice(handlers.indexOf(handler), 1); if(handlers.length == 0){ $interval.cancel(promise); } } } }]); 

Comme indiqué ici, https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form

L'interface utilisateur Google Chrome pour les requêtes de remplissage automatique varie, selon que l'autocomplete est désactivé sur les éléments d'entrée ainsi que leur forme. Plus précisément, lorsqu'un formulaire a été désactivé automatiquement et que son champ d'autocomplète n'est pas défini, si l'utilisateur demande des suggestions de remplissage automatique pour l'élément de saisie, Chrome peut afficher un message indiquant que "l'autocomplète a été désactivé pour ce formulaire". D'autre part, si la forme et l'élément de saisie ont été désactivés automatiquement, le navigateur ne affichera pas ce message. Pour cette raison, vous devez désactiver automatiquement la fonction de saisie automatique pour chaque entrée ayant une auto-exécution personnalisée.

Vous devez configurer autocomplete = "off" en form et en input

Je ne pense pas que cela soit lié à AngularJS

J'ai eu le même problème et j'ai trouvé une solution très simple qui utilise simplement jQuery pour saisir la valeur lors de la soumission. Dans mon contrôleur, j'ai le suivant:

 $scope.username = ""; $scope.password = ""; $scope.login = function(){ $scope.username = $("#username").val(); $scope.password = $("#password").val(); // Proceed as normal }; 

Il y a des inconvénients, si vous avez besoin de faire une validation, etc. mais sinon c'est bon pour les formulaires plus petits comme celui-ci.

De: https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion

Si un auteur souhaite empêcher le remplissage automatique des champs de mot de passe dans les pages de gestion des utilisateurs où un utilisateur peut spécifier un nouveau mot de passe pour quelqu'un d'autre que lui-même, il faut préciser s'il-vous-plaît = "nouveau mot de passe", même si le support n'a pas été implémenté Tous les navigateurs encore.

Alors, qu'est-ce qui me permet de fonctionner?

  • Set autocomplete = "new-password" dans le champ du mot de passe
  • Définissez autocomplete = "off" sur le champ username.

J'espère que cela fonctionne aussi pour vous 🙂

Vous pouvez regarder la valeur du champ de messagerie et, chaque fois que la valeur dans ce champ change, vous pouvez déclencher un "changement" – event sur le champ du mot de passe. Ces événements déclenchent toute la magie du modèle ng sur ce domaine et met à jour le modèle.

 module.directive("autocompleteFor", function () { return { restrict: "A", link: function ($scope, $element, $attrs) { $scope.$watch($attrs.autocompleteFor, function () { $element.triggerHandler("change"); }) } } }); 

Avec cette directive, vous pouvez gérer ce scénario comme ceci:

 <input type="email" name="email" ng-model="user.email"> <input type="password" autocomplete-for="user.email" name="password" ng-model="user.password" required> ----------------------------- 

Pour désactiver l'autocomplete / auto-remplissage à partir d'une entrée, tapez simplement: – autocomplete = "false" au lieu d'autocomplete = "off"!

J'ai pu désactiver l'autocomplète (assez étrange) en ajoutant ce qui suit.

 <form ... novalidate> <input ... formnovalidate /> 

Référencez ce plongeur

La directive ci-dessous a fonctionné pour moi. C'est une solution simple et propre. J'espère que cela pourra aider!

Ref: contournement automatique du navigateur AngularJS en utilisant une directive

Voici une solution qui est beaucoup moins difficile que d'autres solutions présentées et est sémantiquement sonore. AngularJS: http://victorblog.com/2014/01/12/fixing-autocomplete-autofill-on-angularjs-form-submit/

 myApp.directive('formAutofillFix', function() { return function(scope, elem, attrs) { // Fixes Chrome bug: https://groups.google.com/forum/#!topic/angular/6NlucSskQjY elem.prop('method', 'POST'); // Fix autofill issues where Angular doesn't know about autofilled inputs if(attrs.ngSubmit) { setTimeout(function() { elem.unbind('submit').submit(function(e) { e.preventDefault(); elem.find('input, textarea, select').trigger('input').trigger('change').trigger('keydown'); scope.$apply(attrs.ngSubmit); }); }, 0); } }; }); 

Ensuite, vous simplement attacher la directive à votre formulaire:

 <form ng-submit="submitLoginForm()" form-autofill-fix> <div> <input type="email" ng-model="email" ng-required /> <input type="password" ng-model="password" ng-required /> <button type="submit">Log In</button> </div> </form> 

Ma solution pour chrome 35.0, firefox 30.0, angulaire 1.2.18 (page de connexion avec mot de passe, remplissage automatique, méthode angulaire et redirection):

https://stackoverflow.com/a/24569358/3619657

@catfish tbosch a écrit un polyfill pour y remédier. Vous pouvez également essayer cela. C'est ici:

https://github.com/tbosch/autofill-event

Ancienne question, mais quoi que ce soit

J'ai rencontré le même problème et j'ai une petite solution "hack". Ce problème s'est produit à plusieurs endroits de mon application, donc j'ai créé une directive pour la réutilisation.

 module.directive("fakeAutocomplete", [ function () { return { restrict: "EA", replace: true, template: "<div><input/><input type=\"password\"/></div>", link: function (scope, elem, attrs) { elem.css({ "overflow": "hidden", "width": "0px", "height": "0px" }); } } } ]); 

Et simplement ajouter

 <fake-autocomplete></fake-autocomplete> 

Au début de votre formulaire, le navigateur détectera les faux champs comme ceux qui devraient être remplis automatiquement. Il suffit de mettre l' display:none sur les champs ne semble plus fonctionner, je l'ai testé.

Dans mon cas, j'ai configuré la propriété autocomplete = "off" dans la forme et la saisie.

 <form autocomplete="off"> <input type="text" autocomplete="off"> </form> 

Cela pourrait être une solution beaucoup plus simple au problème.

  1. Angularjs n'a pas pu "voir" la valeur
  2. Prenez la valeur via DOM (jQuery) puis remettez-le dans Angularjs.

“ `

 angular.module('someModule').directive('chromeAutofillHack', function() { return { require: '^ngModel', restrict: 'A', priority: 500, // set higher priority then other custom directives link: function(scope, element, attrs , ngModelCtrl) { ngModelCtrl.$parsers.unshift(function(email) { if (!email) { // only do this when angular think there is no value email = $(element).val(); ngModel.$setViewValue(email); } return email; }); } }; }); 

“ `