2019,Chrome 76,自动完成关闭方法

时间:2019-08-06 01:31:43

标签: forms google-chrome autocomplete street-address

关于此的文章很少。您花费数小时来仔细研究每个答案,测试,阅读评论,以发现没有解决方案。您在2019年做了什么工作,Chrome 76正常运行?

13 个答案:

答案 0 :(得分:13)

TL,DR:autocomplete属性似乎没有设置可以可靠地关闭所有自动完成下拉菜单。但是,导致这种情况的情况令人费解,值得记录,以期希望清除大量相互矛盾的建议...

当前(76.0.3809.132)版本的Chrome中存在两种不同的机制,我们将其称为“自动填充”和“自动填充”(不一定是其官方名称):

自动填充

Autofill example: a dropdown showing two postcodes and a "Manage addresses..." option

“自动填充”功能尝试使用存储在浏览器设置中的地址信息填写表格。可以通过下拉菜单底部的“管理地址...”选项(或类似名称)进行标识。 Chrome开发人员是故意决定使用autocomplete="off"autocomplete="false"这个功能的。

a statement outlining this decision中,zkoch提供了以下解决方法:

  

如果您确实要禁用自动填充功能,我们的建议为   这是利用自动完成属性赋予有效值,   字段的语义含义。如果遇到自动完成   我们无法识别的属性,我们不会尝试填充它。

     

例如,如果您的CRM工具中有一个地址输入字段   您不希望Chrome自动填充,您可以为其赋予语义   相对于您的要求有意义的含义:例如   autocomplete =“ new-user-street-address”。如果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 example: a dropdown showing a previously submitted form value

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

结论

无法通过autocomplete下拉菜单关闭自动填充下拉菜单;禁用“自动填充”的任何值都会使“自动填充”保持启用状态,反之亦然。任何认为自己找到了可行解决方案的人(通过autocomplete或其他诸如CSS hacks的方法)都应检查其是否符合两种机制。

不幸的是,要说服Chrome的开发人员这已被打破,将是艰巨的努力。 Autofill的开发人员显然认为,他们在为Web开发人员提供替代方案时做出了明智的决定来破坏autocomplete="off"。这种替代方法被打破了,原因是比他们意识到的更微妙的原因。从他们的角度来看,产生的howls of protest来自心怀不满的开发人员,他们懒得跳过一个小箍并更新其autocomplete="off"属性。在所有杂音中,消息都无法通过:环已损坏。

答案 1 :(得分:2)

*此答案不正确。我发布了一个更好(但更难看)的解决方案作为新答案,并保留了该答案,因为某些部分可能仍然有用。如果那不是解决堆栈溢出错误答案的方法,请随时删除此**

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

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

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

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

注意:

  • 与gasman的回复相比,此处使用的术语“自动完成”和“自动填充”被交换。

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

答案 2 :(得分:2)

尝试在您的输入字段中使用type="search"代替“文本”,我已经做了好几次了,并且对我有用。

答案 3 :(得分:1)

正如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">

答案 4 :(得分:1)

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

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

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

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

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

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

PS:这个答案是我以前的解决方案的一个错误,这个解决方案比较干净,但是没有经过充分测试,而且-正如加斯曼正确指出的那样-不适用于普通形式。这个新的解决方案已在Chrome Canary 79上进行了测试,可以正常工作,影响较小,并且可以很好地降级。尽管如此,我还是对发布此hack感到内and,如果我遇到真实的形式,我会感到更加内。它很脏。

注意1:防止存储有意义的唯一方法是不首先设置name属性(或取消设置),这需要拦截Submit事件才能发布。数据“手动”(使用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

答案 5 :(得分:1)

在 Chrome 91 中

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

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

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

PHP 7 示例

printf("%snew",
    filedata->string_table + (X)->sh_name);

限制

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

答案 6 :(得分:0)

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

autocomplete="off"这样的标准方法现在对于最新版本的Chrome几乎可以正常工作。除了这一点:

Chrome's auto-completion list for Manage Addresses

这件事真是令人讨厌,因为它不仅不尊重"nope"之类的标准/非标准值,而且实际上没有办法将其关闭,除非输入甚至与无关。 “地址” 条款。

到底如何不使用与地址相关的单词就能显示与地址相关的输入字段? 这是有史以来最简单的解决方案。

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

  • 这是最关键的部分::如果您需要对文本输入或其任何相邻元素使用任何人类可读的地址术语,请插入“不可见” 空字符(&#0;)。这样,我们就可以欺骗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>

然后您就去了。不再有用于管理地址的令人讨厌的菜单,也没有任何常规的自动完成菜单。

答案 7 :(得分:0)

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');
});

答案 8 :(得分:0)

尝试一下,我使用了这个小技巧,并且一直有效到现在(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);
})

答案 9 :(得分:0)

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

用于表单标签,参数少,可以与其他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

如果你有想法,请 fork

答案 10 :(得分:-3)

autocomplete='nope'

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

答案 11 :(得分:-3)

我遇到了同样的问题。我所做的只是将autocomplete = off设置为关闭。如果autocomplete = nope,则不起作用。不知道为什么。自动填充(autocomplete)开发人员很混乱,仍然有很多抱怨,但那些家伙仍继续保持领先地位。

答案 12 :(得分:-3)

也许您可以尝试使用chrome实验标志进行一些训练。

您可以使用chrome flags访问它并搜索自动填充/自动完成功能。