我遇到了chrome自动填充行为的几个形式的问题。

表单中的字段都有非常常见和准确的名称,例如“email”、“name”或“password”,并且它们还设置了autocomplete=“off”。

自动完成标志已经成功禁用了自动完成行为,当你开始输入时,会出现一个下拉的值,但没有改变Chrome自动填充字段的值。

这种行为是可以的,除了chrome填充输入不正确,例如填充电话输入与电子邮件地址。客户抱怨过这个问题,所以它被证实在很多情况下都发生了,而不是我在我的机器上本地操作的某种结果。

目前我能想到的唯一解决方案是动态生成自定义输入名称,然后在后端提取值,但这似乎是一种相当笨拙的解决这个问题的方法。是否有任何标签或怪癖,改变自动填充行为,可以用来解决这个问题?


当前回答

所以显然,最好的修复/黑客现在不再工作,再次。我使用的Chrome版本是49.0.2623.110 m和我的帐户创建形式现在显示保存的用户名和密码与形式无关。由于铬!其他黑客似乎很可怕,但这个黑客不那么可怕……

为什么我们需要这些黑客工作是因为这些形式通常是帐户创建形式,即不是登录形式,应该允许填写密码。帐户创建表单您不希望删除用户名和密码的麻烦。从逻辑上讲,这意味着在呈现时永远不会填充密码字段。所以我使用了一个文本框,加上一点javascript。

<input type="text" id="password" name="password" />

<script>
    setTimeout(function() {
        $("#password").prop("type", "password");
    }, 100); 
    // time out required to make sure it is not set as a password field before Google fills it in. You may need to adjust this timeout depending on your page load times.
</script>

我认为这是可以接受的,因为用户不会在短时间内获得密码字段,并且如果该字段是密码字段,则发送回服务器没有任何区别,因为无论如何它都是以纯文本发送回来的。

Caveat: If, like me, you use the same creation form as an update form things might get tricky. I use mvc.asp c# and when I use @Html.PasswordFor() the password is not added to the input box. This is a good thing. I have coded around this. But using @Html.TextBoxFor() and the password will be added to the input box, and then hidden as a password. However as my passwords are hashed up, the password in the input box is the hashed up password and should never be posted back to the server - accidentally saving a hashed up hashed password would be a pain for someone trying to log in. Basically... remember to set the password to an empty string before the input box is rendered if using this method.

其他回答

最新的解决方案是添加autocomplete="new-password"到密码字段,以防止Chrome自动填充它。

然而,正如sibbl所指出的,这并不会阻止Chrome在表单提交完成后要求你保存密码。在Chrome 51.0.2704.106中,我发现你可以通过添加一个不可见的虚拟密码字段来实现这一点,该字段还具有属性autocomplete="new-password"。注意,“display:none”在这种情况下不起作用。在真正的密码字段之前添加如下内容:

<input type="password" autocomplete="new-password" 
style="visibility:hidden;height:0;width:1px;position:absolute;left:0;top:0">`

这只适用于当我将宽度设置为非零值时。感谢tibalt和fareed namrouti给出的原始答案。

试试这个。我知道这个问题有点老了,但这是解决这个问题的另一种方法。

我还注意到这个问题出现在密码字段的上方。

两种方法我都试过了

<form autocomplete="off">和<input autocomplete="off">,但它们都不适合我。

所以我使用下面的代码片段修复了它-只是在密码类型字段上方添加了另一个文本字段,并使其显示为:none。

就像这样:

<input type="text" name="prevent_autofill" id="prevent_autofill" value="" style="display:none;" />
<input type="password" name="password_fake" id="password_fake" value="" style="display:none;" />
<input type="password" name="password" id="password" value="" />

希望它能帮助到一些人。

而不是“这对我来说是有效的”的答案和其他看起来完全像黑客的答案……这是目前chrome(和最新的规范)将如何处理输入元素上的自动完成属性:

https://developers.google.com/web/fundamentals/design-and-ui/input/forms/label-and-name-inputs?hl=en

TLDR:在您的输入上添加autocomplete='<value>',其中<value>应该是定义字段用途的任何字符串。这类似于name属性。尽可能使用上面链接上的建议值。

另外,从表单中删除autocomplete属性

以下是我提出的解决方案,因为谷歌坚持推翻人们似乎做出的每一个变通办法。

选项1 -选择所有文本点击

为你的用户设置输入的值为一个例子(例如your@email.com),或者字段的标签(例如Email),并在你的输入中添加一个名为focus-select的类:

<input type="text" name="email" class="focus-select" value="your@email.com">
<input type="password" name="password" class="focus-select" value="password">

下面是jQuery:

$(document).on('click', '.focus-select', function(){
  $(this).select();
});

我真的看不出Chrome会搞砸数值。那太疯狂了。希望这是一个安全的解决方案。

选项2 -设置电子邮件值为一个空间,然后删除它

假设您有两个输入,例如电子邮件和密码,将电子邮件字段的值设置为“”(一个空格),并添加属性/值autocomplete=“off”,然后使用JavaScript清除此设置。您可以将密码值保留为空。

如果用户出于某种原因没有JavaScript,请确保您在服务器端修改了他们的输入(无论如何您都应该这样做),以防他们不删除空格。

下面是jQuery:

$(document).ready(function() {
  setTimeout(function(){
    $('[autocomplete=off]').val('');
  }, 15);
});

我将超时设置为15,因为5似乎在我的测试中偶尔可以工作,所以将这个数字增加三倍似乎是一个安全的赌注。

如果没有将初始值设置为空格,Chrome会让输入框显示为黄色,就好像它已经自动填充了一样。

选项3 -隐藏输入

把这个放在表单的开头:

<!-- Avoid Chrome autofill -->
<input name="email" class="hide">

CSS:

.hide{ display:none; }

确保您保留了HTML注释,这样其他开发人员就不会删除它!还要确保隐藏输入的名称是相关的。

我也遇到过同样的问题。这里是禁用自动填充用户名和密码的Chrome解决方案(仅在Chrome上测试)

    <!-- Just add this hidden field before password as a charmed solution to prevent auto-fill of browser on remembered password -->
    <input type="tel" hidden />
    <input type="password" ng-minlength="8" ng-maxlength="30" ng-model="user.password" name="password" class="form-control" required placeholder="Input password">