我创建了一个使用标签框下拉菜单的Web应用程序。在所有浏览器中都很好,除了Chrome浏览器(版本21.0.1180.89)。
尽管input字段和form字段都具有autocomplete =“off”属性,但Chrome仍然坚持显示先前输入的字段的下拉历史记录,这将覆盖标签框列表。
我创建了一个使用标签框下拉菜单的Web应用程序。在所有浏览器中都很好,除了Chrome浏览器(版本21.0.1180.89)。
尽管input字段和form字段都具有autocomplete =“off”属性,但Chrome仍然坚持显示先前输入的字段的下拉历史记录,这将覆盖标签框列表。
防止用户名(或电子邮件)和密码自动填充:
<input type="email" name="email"><!-- Can be type="text" -->
<input type="password" name="password" autocomplete="new-password">
防止字段自动填充(可能不起作用):<input type="text" name="field" autocomplete="nope">
解释:
autocomplete 属性即使设置为 autocomplete="off",仍然会在 <input> 标签上生效。但你可以将属性值改为一个随机字符串,例如 nope。
其他人尝试禁用表单自动完成的 "解决方案" (虽然并不是正确的方法,但确实可以生效):
1.
HTML:
<input type="password" id="some_id" autocomplete="new-password">
JS (onload):
(function() {
var some_id = document.getElementById('some_id');
some_id.type = 'text';
some_id.removeAttribute('autocomplete');
})();
或者使用jQuery:
$(document).ready(function() {
var some_id = $('#some_id');
some_id.prop('type', 'text');
some_id.removeAttr('autocomplete');
});
2.
HTML:
<form id="form"></form>
JS(onload):
(function() {
var input = document.createElement('INPUT');
input.type = 'text';
document.getElementById('form').appendChild(input);
})();
或者使用jQuery:
$(document).ready(function() {
$('<input>', {
type: 'text'
}).appendTo($('#form'));
});
使用jQuery添加多个字段的方法:function addField(label) {
var div = $('<div>');
var input = $('<input>', {
type: 'text'
});
if(label) {
var label = $('<label>', {
text: label
});
label.append(input);
div.append(label);
} else {
div.append(input);
}
div.appendTo($('#form'));
}
$(document).ready(function() {
addField();
addField('Field 1: ');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="form"></form>
适用于:
Chrome:49+
Firefox:44+
更新
现在Chrome似乎忽略了style="display: none;"或style="visibility: hidden;属性。
您可以更改为以下内容:
<input style="opacity: 0;position: absolute;">
<input type="password" style="opacity: 0;position: absolute;">
根据我的经验,Chrome只会自动填写第一个 <input type="password"> 和前一个 <input>。 所以我添加了以下代码:
<input style="display:none">
<input type="password" style="display:none">
回到<form>顶部,案件得以解决。
display: none; 将使元素消失,与自动完成无关。 - Sandun Perera看起来Chrome现在会忽略autocomplete="off",除非它在<form autocomplete="off">标签上。
autocomplete="new-password"。 - Vladimir Hidalgo2021 更新:
将 <input type="text"> 更改为 <input type="search" autocomplete="off" >
就这样了。下面的回答仅供怀旧之用。
为了可靠的解决方法,您可以将此代码添加到您的布局页面中:
<div style="display: none;">
<input type="text" id="PreventChromeAutocomplete"
name="PreventChromeAutocomplete" autocomplete="address-level4" />
</div>
只有表单中至少有一个具有任何其他自动完成值的输入元素时,Chrome才会尊重autocomplete=off。
这对于密码字段无效 - 在Chrome中,这些字段的处理方式非常不同。详情请参见https://code.google.com/p/chromium/issues/detail?id=468153。
更新:Chromium团队于2016年3月11日关闭了该漏洞。请参见我最初提交的错误报告中的最后一条评论,以获取完整说明。太长不看:使用语义自动完成属性,例如autocomplete="new-street-address",以避免Chrome执行自动填充。
autocomplete="off"属性,type="search"也不起作用。感谢您发现了这个技巧。 - cssyphus只需将您的输入设置为 readonly,并在焦点处将其移除即可。这是一种非常简单的方法,浏览器不会填充readonly 输入框。因此,这种方法得到了接受,并且永远不会被未来的浏览器更新覆盖。
<input type="text" onfocus="this.removeAttribute('readonly');" readonly />
下一部分是可选的。根据需要对输入进行样式设置,以使其看起来不像只读输入。
input[readonly] {
cursor: text;
background-color: #fff;
}
TL;DR: 告诉Chrome这是一个新的密码输入,它就不会提供旧密码作为自动完成建议:
<input type="password" name="password" autocomplete="new-password">
autocomplete="off"由于设计决策不起作用 - 大量研究表明,如果用户可以将密码存储在浏览器或密码管理器中,则他们的密码更长且更难被破解。
autocomplete的规范已经改变,现在支持各种值来使登录表单易于自动完成:
<!-- Auto fills with the username for the site, even though it's email format -->
<input type="email" name="email" autocomplete="username">
<!-- current-password will populate for the matched username input -->
<input type="password" autocomplete="current-password" />
如果您未提供这些信息,Chrome仍会尝试猜测,当它这样做时会忽略autocomplete="off"。
解决方案是密码重置表单也存在autocomplete值:<label>Enter your old password:
<input type="password" autocomplete="current-password" name="pass-old" />
</label>
<label>Enter your new password:
<input type="password" autocomplete="new-password" name="pass-new" />
</label>
<label>Please repeat it to be sure:
<input type="password" autocomplete="new-password" name="pass-repeat" />
</label>
你可以使用autocomplete="new-password"标志告诉Chrome不要猜测密码,即使它为该网站存储了一个密码。
Chrome还可以直接使用凭据管理API来管理网站的密码,这是一种标准,并且最终可能会得到普遍支持。
autocomplete="new-password"只是一个hack - 它是2017年最好的解决方法,但正如我在原帖中所说(正确或错误),Chrome团队希望使密码自动完成。type="password"告诉浏览器将其视为密码 - 如果您想要一个不应被当作密码(即不被密码管理器找到)的遮蔽输入,则唯一可靠的方法是自己编写代码。 - Keith很抱歉来晚了,但似乎有一些误解关于autocomplete应该如何工作和不应该工作。根据HTML规范,用户代理(在这种情况下是Chrome)可以覆盖autocomplete:
https://www.w3.org/TR/html5/forms.html#autofilling-form-controls:-the-autocomplete-attribute
用户代理可能允许用户覆盖元素的自动填充字段名称,例如将其从“off”更改为“on”,以便记住值并预先填充,尽管页面作者反对,或者始终“off”,永远不会记住值。但是,用户代理不应该允许用户轻易地将自动填充字段名称从“off”更改为“on”或其他值,因为如果所有值始终被记住,则对用户存在重大安全影响,无论网站的偏好如何。
因此,在Chrome的情况下,开发人员基本上说“我们将让用户在其喜好中决定是否要启用autocomplete。如果您不想要它,请勿在浏览器中启用它”。
然而,对于我来说,他们的做法似乎有点过于热心了,但这就是事实。该规范还讨论了此举可能带来的潜在安全影响:
“off”关键字表示控件输入数据特别敏感(例如核武器的激活代码);或者它是永远不会被重用的值(例如银行登录的一次性密钥),因此用户必须每次显式输入数据,而不是能够依赖UA为他预填充该值;或者文档提供其自己的自动完成机制,并且不希望用户代理提供自动完成值。
所以,在经历与其他人相同的挫折后,我找到了适合我的解决方案。它类似于autocomplete="false"的答案。
Mozilla的一篇文章正好涉及这个问题:
在某些情况下,即使将autocomplete属性设置为off,浏览器仍然会保留建议的自动完成值。这种意外的行为对开发人员来说可能相当令人困惑。真正强制不完成的技巧是将一个随机字符串分配给属性。
因此,以下代码应该可行:
autocomplete="nope"
每个以下的内容也应该是这样:
autocomplete="false"
autocomplete="foo"
autocomplete="bar"
我看到的问题是,浏览器代理可能足够聪明,学习autocomplete属性,并在下一次看到表单时应用它。如果确实如此,我唯一能想到仍然解决问题的方法是,在生成页面时动态更改autocomplete属性值。
值得一提的一点是,许多浏览器将忽略登录字段(用户名和密码)的autocomplete设置。正如Mozilla文章所述:
“出于这个原因,许多现代浏览器不支持为登录字段启用autocomplete =”off“。”
最后,关于属性是否属于form元素或input元素的一些信息。规范再次给出了答案:
“如果省略了自动完成属性,则使用与元素的表单所有者的自动完成属性状态相对应的默认值(“on”或“off”)。如果没有表单所有者,则使用值“on”。”
因此,将其放在表单上应适用于所有输入字段。将其放在单个元素上应仅适用于该元素(即使表单中没有该元素)。如果根本未设置autocomplete,则默认为on。
禁用整个表单的autocomplete:
<form autocomplete="off" ...>
或者如果你需要动态地进行操作:
<form autocomplete="random-string" ...>
要在单个元素上禁用autocomplete(无论表单设置是否存在)
<input autocomplete="off" ...>
或者,如果你需要动态地实现它:
<input autocomplete="random-string" ...>
记住,某些用户代理甚至可以覆盖您最努力的禁用 autocomplete 的尝试。
select标签,这意味着他们遇到的问题不是密码字段(尽管它也可能是一个问题字段)。此外,new-password是规范中的提示,浏览器可能会或可能不会仅针对密码字段遵循它。因此,如果在某些情况下new-password并不总是适用于密码字段,请不要感到惊讶。 - Hooligancat我通过使用随机字符解决了与Google Chrome的不断斗争。当您始终使用随机字符串呈现自动完成时,它将永远不会记住任何内容。
<input name="name" type="text" autocomplete="rutjfkde">
希望能对其他人有所帮助。
更新于2022年:
Chrome进行了这个改进:autocomplete="new-password",这将解决它,但我不确定Chrome是否会在一段时间后再次更改其功能。
目前的解决方案是使用 type="search"。Google不会对type为search的输入应用自动填充。
参见:https://twitter.com/Paul_Kinlan/status/596613148985171968
更新于04/04/2016:看起来这个问题已经解决!请参见http://codereview.chromium.org/1473733008
浏览器不理会autocomplete = off,自动填充到错误的文本字段?
我通过在用户单击或使用Tab键进入字段时将密码字段设置为只读并激活它来解决了这个问题。
修复浏览器自动填充:在鼠标单击和通过字段进行制表符切换时,将字段设置为只读,并在焦点上设置可写
<input type="password" readonly
onfocus="$(this).removeAttr('readonly');"/>
更新: 移动 Safari 在字段中设置光标,但不显示虚拟键盘。新的修复程序与之前的工作方式相同,但处理虚拟键盘:
更新: Mobile Safari 在文本框内设置光标,但不显示虚拟键盘。新的修复方法与之前类似,但可以处理虚拟键盘:
<input id="email" readonly type="email" onfocus="if (this.hasAttribute('readonly')) {
this.removeAttribute('readonly');
// fix for mobile safari to show virtual keyboard
this.blur(); this.focus(); }" />
演示: https://jsfiddle.net/danielsuess/n0scguv6/
// 更新结束
顺便说一下,关于我的观察,更多信息:
有时我注意到在 Chrome 和 Safari 上出现了奇怪的行为,当表单中有密码字段时。我猜测浏览器会寻找密码字段来插入你保存的凭据。然后,它会将用户名自动填充到最靠近密码字段前面的文本输入字段中(只是根据观察做出的猜测)。由于浏览器是最后一个实例,无法控制,即使设置了 autocomplete=off,有时也不能防止将凭据填入错误的字段中,但不会填入用户或昵称字段。