【问题标题】:2019, Chrome 76, approach to autocomplete off2019,Chrome 76,关闭自动完成的方法
【发布时间】:2019-12-13 12:30:54
【问题描述】:

关于这个的帖子很少。您花费数小时检查每个答案、测试、阅读 cmets,以发现没有解决方案。你在 2019 年做了什么,Chrome 76 有效?

【问题讨论】:

    标签: forms google-chrome autocomplete street-address


    【解决方案1】:

    2020 年 1 月更新:似乎从 Chrome 79 开始,自动完成(定义见此处)不再将 autocomplete="some-unrecognised-value" 视为等于 autocomplete="on",所以现在 autocomplete="nope" 或类似有效禁用自动完成和自动填充。

    2020 年 4 月更新:他们再次更改了它。从 Chrome 81 开始,autocomplete="some-unrecognised-value" 在禁用自动完成机制方面不再有效。然而,自动填充现在似乎比以前保守得多——它仍然不符合规范(带有name="email"autocomplete="off" 的字段仍会收到自动填充建议),但它不提供虚假地址随机表单字段上的片段。因此,我现在的建议是使用autocomplete="off"。如果您想在名为 email 的字段上执行此操作,那么您可能不走运:-(


    TL,DR:autocomplete 属性似乎没有设置可以可靠地关闭所有自动完成下拉菜单。然而,导致这种情况的情况非常复杂,值得记录,希望能清除大量相互矛盾的建议......

    当前 (76.0.3809.132) 版本的 Chrome 中存在两种不同的机制,我们将其称为 Autofill 和 Autocomplete(不一定是它们的正式名称):

    自动填充

    自动填充功能会尝试使用您浏览器设置中存储的地址信息来填写表格。它可以通过下拉列表底部的“管理地址...”选项(或类似选项)来识别。此功能不尊重 autocomplete="off"autocomplete="false",这是 Chrome 开发人员的深思熟虑的决定。

    a statement outlining this decision,zkoch 提供了这个解决方法:

    如果您真的想禁用自动填充,我们的建议是 这一点是利用autocomplete属性给出valid, 您的领域的语义含义。如果我们遇到自动完成 我们无法识别的属性,我们不会尝试填充它。

    例如,如果您的 CRM 工具中有地址输入字段 你不想让 Chrome 自动填充,你可以给它语义 这意味着相对于您的要求是有意义的:例如 自动完成=“新用户街道地址”。如果 Chrome 遇到这种情况,它 不会尝试自动填充该字段。

    这是尝试解决方案的基础,例如autocomplete="nope";自动填充机制将跳过它无法识别的具有autocomplete 属性值的任何字段。

    实现此决定的代码,记录在案:https://chromium.googlesource.com/chromium/src/+/refs/tags/78.0.3903.1/components/autofill/core/browser/form_structure.cc#1218

    自动完成

    自动完成功能提供了该表单字段中先前提交的值的下拉列表。此下拉列表没有“管理地址...”选项。自动完成确实支持autocomplete="off"autocomplete="false" 属性;任何其他值(包括“无效”值,例如 autocomplete="nope")都会使其保持启用状态。

    结论

    无法通过autocomplete 下拉菜单关闭自动完成下拉菜单;任何禁用自动填充的值都将启用自动完成,反之亦然。任何认为自己找到了可行的解决方案(通过autocomplete 或其他方法,例如 CSS hacks)的人都应该检查它是否适用于两种机制。

    不幸的是,要让 Chrome 的开发人员相信这已被破坏,可能会是一场艰苦的斗争。 Autofill 的开发人员显然认为他们做出了一个经过深思熟虑的决定,即打破autocomplete="off",同时为 Web 开发人员提供替代方案;由于比他们意识到的更微妙的原因,这种选择被打破了。从他们的角度来看,由此产生的howls of protest 来自心怀不满的开发人员,他们懒得跳过一个小圈子并更新他们的autocomplete="off" 属性。在所有的噪音中,信息没有通过:箍坏了。

    【讨论】:

    • autocomplete="nope" 等似乎不适用于 Chrome 80,用于自动填充
    • 这是我读过的最好的解释,现在清楚多了。非常感谢。
    【解决方案2】:

    尝试在您的输入字段中使用type="search" 而不是“文本”,我已经这样做了几次,它对我有用。

    【讨论】:

    • 我多年来一直在寻找答案......不,错误 - 没有任何效果,但这确实有效。截至 2019 年 11 月 4 日
    • 我很高兴它有效。我也一直在寻找解决方案太久。谷歌 Chrome 团队希望能够采纳开发者多年来一直在讨论的言论。
    • 这适用于 chrome 78 | macOS 10.13。让我们看看 chrome 负责“修复”这个问题需要多少时间...... :-S
    • 工作于 2021 年 2 月 23 日。我一直在寻找许多解决方案,最后终于成功了。
    • 对 type="tel" 这样的情况没有用处。
    【解决方案3】:

    截至 2019 年 12 月 6 日,Chrome v78.x

    autocomplete="off" 等标准方法现在几乎可以用于最新版本的 Chrome。除了这个:

    这东西真的很糟糕,因为它不仅不尊重"nope" 之类的标准/非标准值,而且实际上没有办法关闭它,除非输入甚至与 "addressy 没有远程关系" 条款。

    如果不使用与地址相关的词,我们究竟如何才能显示与地址相关的输入字段? 这是有史以来最简单的解决方案。

    • 确保输入元素的 nameid 不包含任何与地址相关的字词。 id="input-street"name="destination-zip" 之类的属性是大忌。

    • 这是最关键的部分:如果您需要对文本输入或其任何相邻元素使用任何人类可读的地址术语,请插入“不可见”零宽度joiner (‌) 在所述术语的字母之间。通过这种方式,我们可以欺骗 Chrome 的 AI 能力并绕过其严格的自动补全行为。

    一些工作示例:

    <input id="input-stret" placeholder="S&zwnj;treet" autocomplete="off">
    
    <form action="/action_page.php">
      <label for="product-addres">Product A&zwnj;ddress</label>
      <input name="addres" id="product-addres" autocomplete="off">
    </form>
    

    然后就可以了。不再有用于管理地址的烦人菜单,也没有任何常规的自动完成菜单。

    【讨论】:

    • 我现在使用的是 Chrome 80。在&lt;input&gt; 中没有nameid 属性的空字符对我来说很好用(在&lt;label&gt; 中的每个单词中)。困难的部分来自 Angular (8) 中的双向绑定。我们必须将这个:&lt;label&gt;{{ foo }}&lt;/label&gt; 移动到这个:&lt;label [innerHTML]="foo"&gt;&lt;/label&gt; 并将 foo 中的空字符更改为 &amp;#8205;public const foo: string = 'Fi&amp;#8205;rst Na&amp;#8205;me'; 因为空字符(上面提到的)在 HTML 中呈现时显示为未知字符.我还为每个&lt;input&gt;&lt;form&gt; 使用了autocomplete="off"
    • 由于某种原因,字符 没有工作。我用过 ‌相反,它就像一个魅力。还用下划线替换从 ADDRESS 到 ADDRES_S 的每个名称/ID,它可以欺骗 chrome。没有在其他浏览器上测试。
    • @Kilowog 我认识到使用空字符的局限性。更新了我对零宽度连接器的答案。
    • 2021 年 2 月:如果我使用 autocomplete="off" 并且不在该字段的标签中使用任何描述性词语(例如“填写您的地址”等),那么它可以工作(即没有t 尝试使用保存的地址自动填充/自动完成)
    • @ScottDecker 我不是挑剔,但就用户体验而言,是否可以在不使用“地址”之类的描述性词的情况下创建与地址相关的字段?
    【解决方案4】:

    正如gasman's answer 解释的那样,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">
    

    【讨论】:

    • 我认为问题是关于 chrome 功能而不是关于 HTML 表单中的输入字段。
    【解决方案5】:

    * 此答案不正确。我已经发布了一个更好(但更丑)的解决方案作为新答案并保留了这个答案,因为某些部分可能仍然有用。如果这不是在stackoverflow上处理错误答案的方法,请随意删除这个*

    考虑使用 autocomplete=,其中 对于每个字段和页面加载都是唯一的。

    例如,如果一个字段是在时间戳 TS 请求页面后创建的第 N 个字段,则其 可以选择为 nope__

    对自动完成的影响:由于 是自动完成的自定义值,因此 chromium 不会激活自动完成功能(请参阅form_structure.cc)。

    对自动填充的影响:chromium 通过将其指纹与之前遇到的字段的指纹进行比较来识别字段(请参阅form_field_data.cc)。如果被识别,它可能会提供一个记住值的列表。指纹包含自动完成属性的值。由于没有两个 nonce 相等,因此不会识别任何字段。

    注意事项:

    • 与 gasman 的回复相比,此处使用的术语 autocomplete 和 autofill 互换了。

    • 所有字段都应在客户端动态创建(除非您愿意不缓存页面)。

    【讨论】:

    • 好主意,但是当我在 find-postgraduate-teacher-training.education.gov.uk 上测试它时,它在 Chrome 77.0.3865.90 上对我不起作用 - 在 DOM 检查器中将邮政编码字段设置为 autocomplete="nope_20191017_123" 仍然给出记住的建议来自以前的提交(使用不同的自动完成值)。我可以看到 form_field_data.cc 确实是基于autocomplete_attribute 区分字段 - 也许它已经被规范化为真/假?
    • 我的测试用例(Chrome 78)我确实摆脱了弹出窗口,除了(我昨天才注意到)具有 type="password" 的字段。这很烦人,因为它涉及管理员向其他用户分发的密码。根据我发布的想法,它不应该这样做,所以肯定还有更多内容。我已经考虑过规范化,但我发现它不太可能并且找不到任何这样的代码。我仍在寻找使用 == 运算符的地方。当我进行更多调查时,我会回复(PS。如果你随机化另一个无辜的属性,你会发生什么?)
    • 在阅读link 后为您的表单找到了解决方案。好消息:在您的表单副本上使用随机化方法来消除建议。坏消息:类似的方法,但更突兀/骇人听闻。我必须编辑我的帖子。
    【解决方案6】:

    禁用自动填充: 将自动完成属性设置为非标准值,例如“不”。

    禁用自动完成: 提交表单时,自动完成功能会存储字段名称及其值。 除了将自动完成设置为“off”/“false”(请参阅​​why)之外,没有(几乎,参见注释 1)可以采取任何措施来防止存储。 不幸的是,这不是一个选项,因为它会启用自动填充。

    但是,可以通过将“!”附加到字段名称来防止检索以前的值,其中 在每次页面加载时都是唯一的 (从而使字段名称无法识别)。

    在客户端,这可以通过以下 javascript 行(在页面加载时)来实现:

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

    在服务器端,以“!”开头的部分(如果有)应该从变量名中删除(在接收到 post 变量时)。

    PS:这个答案是对我早期解决方案的勘误表,它更清洁但没有经过充分测试,并且 - 正如 gasman 正确指出的 - 不适用于普通形式。这个新的解决方案在 Chrome Canary 79 上进行了测试,确实有效,影响相对较小并且降级很好。尽管如此,我对发布这个黑客感到内疚,如果我以真实的形式遇到它,我会更加内疚。它*非常*脏。

    注意 1: 阻止存储的唯一方法是首先不设置 name 属性(或取消设置),这需要拦截提交事件以发布数据“手动”(使用 XMLHttpRequest)。由于问题是关于形式的,而且这种策略绕过了传统的形式机制,我没有详细说明这种方法。不过,这是一个更好的解决方案。


    附录:我决定跟进注释 1,因为我真的不喜欢非本地化的解决方案。这是 vanilla JS 中的本地化版本,它将所有影响限制在客户端的单个位置。将其作为脚本附加到文档正文或将其放入文档的 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
    

    【讨论】:

      【解决方案7】:

      在 Chrome 91 中

      您需要使用一个随机值,这意味着每次加载页面时都会更改的值。

      从我所做的测试来看,chrome 似乎记住了它已经遇到的任何属性值,并且会在下一次建议该属性值的最后一次看到的值。因此,如果您输入 autocomplete="nope",chrome 会记住 autocomplete="nope" 等于您输入 autocomplete="nope" 的最后一个值。

      通过使用 chrome 从未见过的唯一随机值,它不会提出任何建议,因为它从未见过该值。

      PHP 7 示例

      <input type="text" name="firstname" autocomplete="<?= bin2hex(random_bytes(10)) ?>" />
      

      限制

      它似乎对地址字段有效,但对登录字段没有影响。我没有使用信用卡字段进行测试。

      【讨论】:

      • 很遗憾,现在这是必要的。我只是希望它停止与我的自定义自动完成重叠。我不会再向任何人推荐这个浏览器了。感谢您的解决方案
      • 在 chrome 92 中,我必须使用随机自动完成值并删除名称和 ID。随机化 name 和 id 字段也是可行的。
      【解决方案8】:

      Chrome 版本 81。

      对我来说,当输入类型为 TEL、EMAIL 或 SEARCH 时,它适用于 autocomplete='disabled'。 当输入类型为 NUMBER 时,它适用于 autocomplete='off'。

      但是当输入类型是 TEXT .. 它可能与 autocomplete='off' 一起使用。如果没有,它将使用 autocomplete='disabled'。

      你可以试试这个,也许它对你有用(它适用于我 95% 的情况):

      // Désactivation de l'autocomplete des input text
      function setAutocomplete(val) {
          var E = document.getElementsByTagName('INPUT');
          for (var i = 0 ; i < E.length ; i++) {
              if (E[i].name == 'txt_nom') { console.log('txt_nom', E[i]); }
              var type = E[i].type.toUpperCase();
              if (E[i].autocomplete != '') { continue; }
              if (type == 'HIDDEN') {
                  //
              } else if (type == 'NUMBER') {
                  E[i].autocomplete = 'off';
              } else if ((type == 'TEL') || (type == 'EMAIL') || (type == 'SEARCH')) {
                  E[i].autocomplete = 'disabled';
              } else {
                  E[i].autocomplete = val;
              }
          }
      }
      
      // Exécution de diverses fonctions à la fin de chaque chargement
      window.addEventListener("load", function() {
          // Désactivation de l'autocomplete des input text
          setAutocomplete('off');
      });
      

      【讨论】:

        【解决方案9】:

        试试这个,我用了这个小技巧,它一直有效到现在(2020 年 9 月)。我希望这对很多人有用

        --HTML--
        <input type="text" name="example" autocomplete="off">
            
        --Javascript--
        let elements = document.querySelectorAll('[autocomplete="off"]');
        elements.forEach(element => {
            element.setAttribute("readonly", "readonly");
            element.style.backgroundColor = "inherit";
            setTimeout(() => {
                element.removeAttribute("readonly");
            }, 500);
        })
        

        【讨论】:

          【解决方案10】:

          我制作了一个小型 jQuery 插件,可以从任何浏览器禁用任何类型的自动完成功能

          用于form标签,参数少,可与其他jQuery方法嵌套。

          $('#login_form').randomizeFormFields();
          

          它改变了这个:

          <form id="login_form" action="" method="post">
            <input type="text" name="email">
            <input type="password" name="secret">
          </form>
          

          进入这个:

          <form id="login_form" action="" method="post">
            <input type="text" name="yQoiFZkCrzwWXN3WWgM8Jblby">
            <input type="password" name="ono1qamA9CzrH4tW2COoRtFKI">
          </form>
          

          提交时保留原始名称

          // returned post (php example)
          array(2) {
            ["email"]=>
            string(16) "email@domain.com"
            ["secret"]=>
            string(19) "supersecretpassword"
          }
          

          https://github.com/cicerogeorge/randomize-form-fields

          如果你有想法,请分叉

          【讨论】:

            【解决方案11】:

            我已尝试对 html 形式的 EmailId 文本框使用 autocomplete = "off" 和 autocomplete = "nope",但它不适用于 Google Chrome。所以我尝试了以下对我有用的更改。

            <input type="email" class="tbx-input" name="Email" style="display:none;">
            
            <input type="email" class="tbx-input" name="Email" id="Email" placeholder=" " required autocomplete="nope">
            

            【讨论】:

              【解决方案12】:
              autocomplete='nope'
              

              这是目前适用于 Chrome 76 的解决方案。

              【讨论】:

              • 这在 Chrome 76.0.3809.100 上为我工作。也许还有另一个混淆因素?如果您发布代码,可能会更容易提供帮助。
              • 根据我的回答 stackoverflow.com/a/57810447/1853523 ,这会禁用 Chrome 的自动填充机制,但不会禁用自动完成。
              猜你喜欢
              • 2020-01-29
              • 1970-01-01
              • 1970-01-01
              • 2019-12-18
              • 2017-04-20
              • 2016-01-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多