web-dev-qa-db-fra.com

2019, Chrome 76, approche de la saisie semi-automatique désactivée

Il y a peu de messages à ce sujet. Vous passez des heures à parcourir chaque réponse, à tester, à lire les commentaires, pour trouver qu'il n'y a pas de solution. Qu'avez-vous fait en 2019, Chrome 76, qui fonctionne?

13
user2060451

Au 6 décembre 2019, avec Chrome v78.x

Les méthodes standard comme autocomplete="off" fonctionnent désormais très bien pour les dernières versions de Chrome. Sauf pour celui-ci:

Chrome's auto-completion list for Manage Addresses

Cette chose est vraiment décevante car elle ne fait pas que manquer de respect aux valeurs standard/non standard comme "nope" mais il n'y a littéralement aucun moyen de désactiver cette option à moins que l'entrée ne soit même pas liée à distance avec les termes "addressy".

Comment diable pourrions-nous afficher les champs de saisie liés à l'adresse sans utiliser de mots liés à l'adresse? Voici la solution la plus simple qui soit.

  • Assurez-vous que name et id de l'élément d'entrée n'incluent aucun terme lié à l'adresse. Des attributs comme id="input-street" ou name="destination-Zip" sont gros non-non.

  • Ceci est la partie la plus cruciale: Si vous devez utiliser des termes d'adresse lisibles par l'homme pour la saisie de texte ou l'un de ses éléments adjacents, insérez le "invisible" caractère nul (�) entre les lettres dudit terme. De cette façon, nous pouvons tromper la capacité d'IA de Chrome et contourner son comportement de saisie semi-automatique strict.

Quelques exemples pratiques:

<input id="input-stret" placeholder="S&#0;treet" autocomplete="off">

<form action="/action_page.php">
  <label for="product-addres">Product A&#0;ddress</label>
  <input name="addres" id="product-addres" autocomplete="off">
</form>

Et voilà. Plus de menus embêtants pour gérer les adresses, ni de menus de saisie semi-automatique standard.

1
filipvkovic

Désactivation du remplissage automatique: Définissez l'attribut de saisie semi-automatique sur une valeur non standard, par ex. "Nan".

Désactivation de la saisie semi-automatique: La fonction de saisie semi-automatique stocke les noms de champ et leurs valeurs lorsqu'un formulaire est soumis. Il n'y a (presque, voir note 1) rien de sensé à faire pour empêcher le stockage, sauf la définition de la saisie semi-automatique sur "off"/"false" (voir pourquoi ). Malheureusement, ce n'est pas une option car cela permettrait le remplissage automatique.

Cependant, il est possible d'empêcher la récupération des valeurs précédentes en ajoutant "! <nonce>" aux noms de champ, où <nonce> est unique par chargement de page (rendant ainsi les noms de champ méconnaissables).

Du côté client, cela peut être réalisé par quelque chose comme la ligne suivante de javascript (lors du chargement de la page):

Array.prototype.slice.call(document.body.getElementsByTagName('INPUT'))
   .forEach(function(elt) { elt.name += '!' + new Date().getTime(); });

Côté serveur, la partie (le cas échéant) commençant par "!" doit être supprimé des noms de variables (lors de la réception des variables de publication).

PS: cette réponse est un erratum à ma solution précédente qui est plus propre mais qui n'a pas été suffisamment testée et - comme Gasman l'a souligné à juste titre - ne fonctionne pas pour les formes ordinaires. Cette nouvelle solution a été testée sur Chrome Canary 79, fonctionne, a un impact relativement faible et se dégrade bien. Pourtant, je me sens coupable de publier ce hack et je me sentirai encore plus coupable si jamais je le rencontre) sous des formes réelles. C'est * très * sale.

Remarque 1: la seule façon d'empêcher le stockage qui fait logique est de ne pas définir l'attribut name en premier lieu (ou de le désactiver), ce qui nécessite l'interception de l'événement submit pour publier les données "manuellement" (à l'aide de XMLHttpRequest). Étant donné que la question porte sur les formulaires et que cette stratégie contourne le mécanisme de formulaire traditionnel, je n'ai pas développé cette approche. C'est une meilleure solution cependant.


Addendum: j'ai décidé de donner suite à la note 1 car je n'aime vraiment pas avoir une solution non localisée. Voici une version localisée dans Vanilla JS qui limite tout impact à un seul endroit côté client. Ajoutez-le en tant que script au corps du document ou placez-le dans le gestionnaire de chargement du document.

function disableInputSuggestions(form) { // note: code uses ECMA5 features 
    // Tweak the inputs of form 
    var inputs = Array.prototype.slice.call(form.getElementsByTagName('INPUT'));
    var nonce = Date.now();
    inputs.forEach(function(input, i) { 
        input.autocomplete = 'nope'; // prevent autocomplete
        input.originalName = input.name || input.id; // to not let this code break form handling of inputs without names (browsers fallback to the id in that case)
        input.name = nonce + '_' + i; // prevent autofill (if you're willing to eliminate all input ids first, then clear the name instead)
    });
    // replace the default submit handler by a custom one 
    form.onsubmit = function(ev) {
        // get the form data using the original variable names
        var formData = new FormData();
        inputs.forEach(function(input) { formData.set(input.originalName, input.value); });
        // submit the form data using XMLHttpRequest (alternatively, use a helper form or temporarily undo the tweaks to form) 
        var submitter = new XMLHttpRequest();
        submitter.open(form.getAttribute('method'), form.getAttribute('action'));
        submitter.onreadystatechange = function() {
            if(submitter.readyState == 4 && submitter.status == 200) {
                // handle the server response, here assuming the default form.target = "_self"  
                document.open();
                document.write(submitter.responseText);
                document.close();
            }
        }
        submitter.send(formData);
        return false; // prevent submitting form
    }; 
}
disableInputSuggestions(document.forms.myForm); // assumed: the form has id = myForm
1
Koen AIS

Comme réponse de gasman l'explique, les fonctionnalités autofill et autocomplete doivent être désactivées, ce qui ne semble pas possible sur une seule entrée.
La seule solution de travail que j'ai trouvée consiste à définir autocomplete="off" sur l'entrée et ajoutez de fausses entrées cachées avant l'entrée réelle qui dupe autofill, comme ceci:

<input name="Fake_Username" id="Fake_Username" type="text" style="display:none">
<input name="Fake_Password" id="Fake_Password" type="password" style="display:none">
<input name="NameInput" id="NameInput" type="text" autocomplete="off">
1
Lucas