web-dev-qa-db-ja.com

2019、Chrome 76、オートコンプリートをオフにするアプローチ

これに関する投稿はほとんどありません。あなたは、解答がないことを見つけるために、各回答をテストし、コメントを読み、何時間も費やしています。 2019年に何をしましたか、Chrome 76、うまくいきましたか?

13
user2060451

2019年12月6日現在、Chrome v78.x

autocomplete="off"などの標準メソッドは、最新バージョンのChromeでほぼ正常に機能するようになりました。これを除いて:

Chrome's auto-completion list for Manage Addresses

これは、"nope"のような標準/非標準の値を無視するだけでなく、入力が「アドレス指定」条件。

いったいどのようにして、住所関連の単語を使用せずに住所関連の入力フィールドを表示できるでしょうか。 これが最も簡単な解決策です

  • 入力要素のnameおよびidに住所関連の用語が含まれていないことを確認してください。 id="input-street"name="destination-Zip"のような属性は非常に重要です。

  • これは最も重要な部分です:テキスト入力またはその隣接要素のいずれかに人間が読めるアドレス用語を使用する必要がある場合は、 「非表示」null文字(�上記の用語の文字の間。このようにして、ChromeのAI機能をだまして、その厳密なオートコンプリート動作をバイパスできます。

いくつかの実際の例:

<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>

そして、あなたは行き​​ます。アドレスを管理するための厄介なメニューや、通常のオートコンプリートメニューはありません。

1
filipvkovic

オートフィルの無効化:オートコンプリート属性を非標準の値に設定します。 「いいえ」。

オートコンプリートを無効にする:オートコンプリート機能は、フォームの送信時にフィールド名とその値を保存します。オートコンプリートを "off"/"false"に設定する以外に、ストレージを防ぐために行うことは(ほとんど、注1を参照)賢明なことはありません( why を参照)。残念ながら、これは自動入力を有効にするオプションではありません。

ただし、フィールド名に「!<nonce>」を追加することで、以前の値の取得を防ぐことができます。ここで、<nonce>はページの読み込みごとに一意です(そのため、フィールド名が認識できなくなります)。

クライアント側では、これは次のJavaScriptの行のようなもの(ページのロード時)によって実現できます。

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

サーバー側では、「!」で始まる部分(ある場合)変数名から削除する必要があります(ポスト変数の受信時)。

PS:この答えは以前の解決策の正誤表です。これはよりクリーンですが十分にテストされていません。ガスマンが正しく指摘したように、通常のフォームでは機能しません。この新しいソリューションは、Chrome= Canary 79でテストされ、動作し、比較的影響が少なく、パフォーマンスが低下します。それでも、このハックの公開については罪悪感を感じます。実際の形でそれは*非常に*汚いです。

注1:が行う意味のあるストレージを防ぐ唯一の方法は、最初にname属性を設定しない(または設定を解除する)ことです。データを「手動で」(XMLHttpRequestを使用して)送信するために、送信イベントをインターセプトする必要があります。質問はフォームに関するものであり、この戦略は従来のフォームメカニズムをバイパスするため、そのアプローチについては詳しく説明していません。しかし、それはより良い解決策です。


補遺:ローカライズされていない解決策が嫌いなため、注1でフォローアップすることにしました。バニラJSのローカライズバージョンを以下に示します。これは、すべての影響をクライアント側の1つのスポットに制限します。スクリプトとしてドキュメントの本文に追加するか、ドキュメントのonloadハンドラーに入れます。

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

ガスマンの答え が説明しているように、autofillautocompleteの両方の機能を無効にする必要があります。これは、単一の入力では不可能のようです。
私が見つけた唯一の実用的な解決策は、autocomplete="off"を入力し、次のようにautofillをだます実際の入力の前に隠し偽の入力を追加します。

<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