Chrome忽略autocomplete="off"属性

724

我创建了一个使用标签框下拉菜单的Web应用程序。在所有浏览器中都很好,除了Chrome浏览器(版本21.0.1180.89)。

尽管input字段和form字段都具有autocomplete =“off”属性,但Chrome仍然坚持显示先前输入的字段的下拉历史记录,这将覆盖标签框列表。


17
从技术上讲,这个问题是在被标记为“此问题已有答案”的那个问题之前大约5个月被提出的。那个被标记的问题是重复的,因为它是在这个问题之后提出的。 - user3071434
84
7年过去了,我们仍然无法正确地禁用自动完成... 真是太遗憾了... - BruneX
3
我在这里得到了解释:https://developer.mozilla.org/zh-CN/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion。 - Muhammad Rosyid
2
请查看 https://bugs.chromium.org/p/chromium/issues/detail?id=370363#c7 链接,该链接建议使用 autocomplete="new-password"。 - Hamid Taebi
不想在所有的答案中再添加一个“答案”,所以只是想评论一下,但在尝试了很多解决方案后,我们在vuejs应用程序搜索过滤器上采用了这个解决方案,因为chrome似乎尊重它:$("input[type='search']").wrapAll("<form autocomplete='off' />"); - jjay225
显示剩余5条评论
69个回答

459

防止用户名(或电子邮件)和密码自动填充:

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


5
最重要的(也是唯一有效的方法)是确保你的<input>字段的ID和Name属性不包含“Username”或“Password”。这样就能在autocomplete="off"时完全停止所有自动填充。 - GONeale
20
“autocomplete="nope"”对我起了作用,但只有当我把它加到我的两个表单字段中时才有效。例如,我可以在任意一个字段上使用它,然后该字段将不再自动完成,但另一个字段仍然会自动完成;但是一旦我在这两个字段上都加上它,它们两个就会重新开始自动完成。 - SeriousLee
4
lol自动完成“没门”运作良好。虽然很有趣。 - Felix
1
是时候开始输入有趣的文本行到自动完成标签了。 - schizoid04
没有用,对我没起作用。 - João Melo
显示剩余8条评论

331

更新

现在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>顶部,案件得以解决。


70
这个解决方案已经不再适用,因为Chrome 40已无法使用。 - user881703
14
这不仅难看,而且我仍然无法找到任何关于“为什么”问题的解释? - Augustin Riedinger
4
看起来现在如果使用了 display: none,Chrome 会忽略它们,所以我用绝对定位将这些字段移到了视图外面... - Christoph Leiter
2
display: none; 将使元素消失,与自动完成无关。 - Sandun Perera
2
@AugustinRiedinger 为什么?因为Chrome强制开发者这样做,因为他们不尊重规范,也不希望任何人禁用他们可怕的自动填充功能,而且永远无法正确填写字段 :叹气: - Tofandel

173

看起来Chrome现在会忽略autocomplete="off",除非它在<form autocomplete="off">标签上。


对于React,请使用“autoComplete = off”。 - zero_cool
1
关于为什么Chrome做出这个更改的解释,请查看这篇答案:https://dev59.com/sF8e5IYBdhLWcg3wYJYN#39689037--他们将用户置于开发者之上。 - Luke
26
如果您想向Chrome团队提供使用autocomplete="off"的有效理由,请在此处提交:https://bugs.chromium.org/p/chromium/issues/detail?id=587466 - Chris
3
针对上述内容,仅作澄清,因为有不一致的报道。在表单标签中添加autocomplete="off",在各个输入标签中添加autocomplete="new-password"。截至Chrome 75版本,此方法有效。 - AndyP9
5
从Chrome 81开始,它现在忽略单独字段中的autocomplete="new-password" - Vladimir Hidalgo
显示剩余4条评论

152

2021 更新:
<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执行自动填充。


2
@Jonathan Cowley-Thom:请尝试我放置的这些测试页面,其中包含我的解决方法。在 https://hub.securevideo.com/Support/AutocompleteOn 上,您应该会看到 Chrome 的自动完成建议。然后,请尝试在 https://hub.securevideo.com/Support/AutocompleteOff 上输入相同的内容。您不应该看到 Chrome 的自动完成建议。我刚在 Chrome 45.0.2454.101m 和 46.0.2490.71m 上进行了测试,并且在两者上都按预期工作。 - J.T. Taylor
请见上文:“这种方法无法在密码字段中使用——因为Chrome对此处理方式有所不同。更多细节请参考https://code.google.com/p/chromium/issues/detail?id=468153。” - J.T. Taylor
现在我建议将<input type="text">更改为<input type="search">。 - J.T. Taylor
3
如果没有autocomplete="off"属性,type="search"也不起作用。感谢您发现了这个技巧。 - cssyphus
3
将输入类型改为搜索(type="search")在类似 type="tel" 的情况下是没有用的。 - mediaguru
显示剩余4条评论

119

现代方法

只需将您的输入设置为 readonly,并在焦点处将其移除即可。这是一种非常简单的方法,浏览器不会填充readonly 输入框。因此,这种方法得到了接受,并且永远不会被未来的浏览器更新覆盖。

<input type="text" onfocus="this.removeAttribute('readonly');" readonly />

下一部分是可选的。根据需要对输入进行样式设置,以使其看起来不像只读输入。

input[readonly] {
     cursor: text;
     background-color: #fff;
}

可运行示例


65
这就是我称之为“现代方法”的原因。全球不到1%的用户关闭JavaScript,所以老实说,为这么小的受众做任何适配都不值得,因为大多数网站都依赖于JavaScript。开发网站已经有很长时间了,我的所有网站100%都使用JavaScript,并且非常依赖它。如果用户关闭了JavaScript,那是他们自己的问题和选择,而不是我的问题。他们将无法访问或使用至少90%的在线网站...你的反对票完全没有意义。 - Fizzix
37
今天在谷歌浏览器49中,这种方法已经不起作用了。"开发人员"正在关注stackoverflow上的解决方案并将其删除。 - puchu
7
这个来自2015年9月的答案基本上是下面2014年11月的答案的复制。请注意,我并未改变原文意思,只是使内容更加通俗易懂的翻译它。 - dsuess
3
这会破坏 HTML 表单中“mandatory”(强制)检查的功能。例如,使用此代码的密码字段在提交前无法强制要求填写。 - abulhol
5
请记住,仅依赖JS进行关键交互不仅会破坏那些停用JS的用户的功能,也会影响那些网络连接缓慢(JS尚未加载)的用户。 - bfontaine
显示剩余7条评论

66

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来管理网站的密码,这是一种标准,并且最终可能会得到普遍支持。


6
并不是一个非常令人信服的理由。用户想要某些东西并不意味着这是个明智的想法。这几乎和说你会允许应用程序中使用单个字符密码一样糟糕,只因为用户觉得更方便。有时,安全性胜过便利性... - Daniel Kotin
我是Chrome用户,我不想要这种行为。它甚至在自动填充密码框之前都没有询问我,而该密码框弹出是为了确保只有我能访问相关的Web应用程序。保存一些密码并不意味着自动完成所有密码。 - Hippyjim
6
这个回答(和谷歌的行为)忽略了一个重要事实,那就是你想这样做的主要原因之一是为了实现自己的自动完成行为(例如,从数据库中列出)。 - squarelogic.hayden
1
你试图为 Chrome 明显错误的决定进行辩护。我正在实施公司的政策,而我无法改变它。所以现在我必须为 Chrome 插入黑客。它们目前可以工作。如果它们停止工作,那么我们公司将更改员工的默认浏览器。因此,现在我们有了相同的行为,但使用黑客和可能破损的页面在未来升级中。看到这里所有这些回答,有很多开发者在使用这些黑客。干得好,Chrome。 - Claudiu Creanga
@Cesar autocomplete="new-password"只是一个hack - 它是2017年最好的解决方法,但正如我在原帖中所说(正确或错误),Chrome团队希望使密码自动完成。type="password"告诉浏览器将其视为密码 - 如果您想要一个不应被当作密码(即不被密码管理器找到)的遮蔽输入,则唯一可靠的方法是自己编写代码。 - Keith
显示剩余2条评论

60

很抱歉来晚了,但似乎有一些误解关于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的一篇文章正好涉及这个问题:

https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion

在某些情况下,即使将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 的尝试。


1
@user2060451 - 什么不起作用?我刚在Windows和Mac上的76.0.3809.87版本测试了它,两者都按照上述规范执行。如果您能提供比“不起作用”更详细的描述,我可能能够帮助您解决问题。 - Hooligancat
1
我刚刚尝试为输入元素自动完成(在所有内容加载并且设置在服务器端之后从控制台中)提供了一个随机字符串,但是它没有起作用。将autocomplete ="off"应用到表单元素也没有起作用。 - Nuryagdy Mustapayev
1
它可以使用随机字符串。从我注意到的情况来看,似乎无论您放置什么属性值,Chrome都会保存它。因此,如果您放置“off”,Chrome将认为“off”等于您输入的值。下次您有一个带有“off”的表单时,Chrome将重用上次的值。使用随机值可以解决这个问题,因为如果该值每次都是新的和独特的,Chrome就从未见过它,并且不会提供任何建议。 - Gudradain
并没有比设置“new-password”更好的效果。 - pishpish
@pishpish - OP的问题没有提到密码字段,而是针对select标签,这意味着他们遇到的问题不是密码字段(尽管它也可能是一个问题字段)。此外,new-password是规范中的提示,浏览器可能会或可能不会仅针对密码字段遵循它。因此,如果在某些情况下new-password并不总是适用于密码字段,请不要感到惊讶。 - Hooligancat

51

永远有效的解决方案

我通过使用随机字符解决了与Google Chrome的不断斗争。当您始终使用随机字符串呈现自动完成时,它将永远不会记住任何内容。

<input name="name" type="text" autocomplete="rutjfkde">

希望能对其他人有所帮助。

更新于2022年:

Chrome进行了这个改进:autocomplete="new-password",这将解决它,但我不确定Chrome是否会在一段时间后再次更改其功能。


当每个渲染都有唯一的随机字符串时,它是不可能被记住的。这就是重点。 - step
2
在Chrome版本99.0.4844.51上,对于电子邮件和密码字段,这对我没有起作用,但是这个可以:autocomplete="new-password"。发现在https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion。 - Jessica
对我也不起作用 - diesel94
1
autocomplete="new-password" 适用于 Chrome 版本-105.0.5195.127。 - Furkan Penbegül
回答之前请仔细思考,不要回答您无法控制的事情。 - pstanton

41

13
这不是真的,v73。 - Miguel
这对我来说是最容易的事情,Chrome 版本为 98.0.4758.102。不过似乎不确定它是否适用于其他版本的 Chrome。 - Joe

28

浏览器不理会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,有时也不能防止将凭据填入错误的字段中,但不会填入用户或昵称字段。


3
我使用setTimeout来清除readonly属性,而不是使用onfocus事件,这样我的用户就看不到输入框是只读的,也不会因为无法获得焦点而感到困惑。 - Hippyjim
只有这个解决方案适用于我。 - cansu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,