在不禁用自动完成的情况下,在Chrome中禁用表单自动填充

51

如何在特定的 <input> 上禁用 Chrome 的自动填充功能,以防止页面加载时自动填充这些输入框?

同时,我需要保持自动完成 (autocomplete) 功能的启用状态,让用户仍然可以通过单击或输入来查看建议列表。这个可行吗?

编辑:如果您认为有必要或认为使用 jQuery 可以使解决方案更简单,请随意使用纯 JavaScript 或 jQuery。


可能相关:https://dev59.com/eHA75IYBdhLWcg3w-OZA (因为它可能不允许任何自动完成操作) - MetalFrog
我尝试将字段命名为不同的名称,但在我的情况下,如果这样做,保持服务器上的工作状态会很棘手。 - Elias Zamaria
是的,我就怕会发生这种情况。不确定该提出什么建议。 - MetalFrog
请在此处检查我的解决方法: https://dev59.com/1GUo5IYBdhLWcg3w1yPH#36030236 - Fareed Alnamrouti
如果您想使用 JavaScript 解决此问题,请尝试使用 https://github.com/terrylinooo/disableautofill.js。 - Terry Lin
显示剩余5条评论
21个回答

86

这就是你想要的魔法:

    autocomplete="new-password"

Chrome故意忽略autocomplete="off"autocomplete="false"。但是,他们添加了一个特殊的子句new-password,以防止自动填充新密码表单。

我在我的密码输入框中加入了上述代码,现在我可以编辑表单中的其他字段,并且密码不会自动填充。


6
如果你的目标是防止密码自动填充,那么这就是正确的解决方案。 - Alex Yuly
从可用性和可访问性的角度来看,这是唯一可接受的解决方案。 - tschoffelen
但是,如果我没记错的话,新密码不也会导致自动完成失效吗?题目明确表示这种情况不应该发生。 - My1
@My1 我认为你是正确的。对于Chrome来说,它们是同一功能的两个部分。因此,这个答案适用于试图禁用两者的人。 - Mirror318
在Chrome 103上对我不起作用。 - Luke Hutchison

43

有些晚了,但这是我的经过验证的解决方案,适用于像注册/登录页面这样的页面,用户必须输入新密码。

<form method="post">
    <input type="text" name="fname" id="firstname" x-autocompletetype="given-name" autocomplete="on">
    <input type="text" name="lname" id="lastname" x-autocompletetype="family-name" autocomplete="on">
    <input type="text" name="email" id="email" x-autocompletetype="email" autocomplete="on">
    <input type="password" name="password" id="password_fake" class="hidden" autocomplete="off" style="display: none;">
    <input type="password" name="password" id="password" autocomplete="off">
</form>

Chrome将检测到两个密码输入框,但不会自动填充密码字段。然而,id="password_fake" 的字段将通过CSS隐藏。因此,用户只能看到一个密码字段。

我还添加了一些额外的属性“x-autocompletetype”,这是Chrome实验性的特定自动填充功能。从我的例子中,Chrome将自动填写名字、姓氏和电子邮件地址,而不是密码字段。


只有这个解决方案对我有效。 - einstein
2
虽然有点乱,但至少它能工作。有趣的是,我在这个表单上也设置了autocomplete="off",虽然对于Firefox来说可以起作用,但对于Chrome来说还不够(可能有充分的理由)。 - Brilliand

27

修复:防止浏览器自动填充

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

更新:移动版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/

// 更新结束

说明 此代码片段不是通过填充空格或窗口加载函数来工作,而是通过设置只读模式,并在用户聚焦于该输入字段时切换为可写模式(聚焦包括鼠标单击和通过字段进行选项卡)。

无需使用jQuery,纯JavaScript。


这样可以避免Chrome的很多奇怪启发式瞎猜...非常感谢!终于不会在搜索框中自动填写用户名了!! - Daniel Gray

12

经过许多努力,我发现解决方案比想象中简单得多:

不要使用 autocomplete="off" ,只需简单地使用 autocomplete="false" ;)

试试这个...

$(document).ready(function () {
    $('input').attr('autocomplete', 'false');
});

有点晚了,但是它会禁用整个表单而不仅仅是一个输入。 - HFR1994
@HFR1994,你可以通过将其更改为$('input#password').attr('autocomplete', 'false');来修复它。 - Meelah
@Meelah 点赞,你是对的。 - HFR1994
这在Chrome 88上不起作用。 - Yousef Altaf

10

今天我偶然发现了奇怪的Chrome自动填充行为。它在名为“embed”和“postpassword”的字段上启用(填写登录和密码),但没有明显的原因。这些字段已经关闭了自动完成功能。

描述的方法似乎都不起作用。另一个答案中的方法也都不起作用。我基于Steele的答案想到了自己的想法(它实际上可能有效,但我需要在我的应用程序中使用修复后的帖子数据格式):

在真正的密码之前,添加这两个虚拟字段:

<input type='text' style='display: none'>
<input type='password' style='display: none'>

只有这个最后让我完全禁用了表单自动填充。

很遗憾,禁用这种基本行为如此困难和hacky。


4
我无法让Chrome在页面加载时自动填充,以进行测试,但您可以尝试向字段添加autocomplete="off",然后在加载时删除该属性。
$(window).load(function() { // can also try on document ready
    $('input[autocomplete]').removeAttr('autocomplete');
});

1
这并不是有帮助的。它禁用了自动填充,但也禁用了自动完成。请参见我的问题。 - Elias Zamaria
2
@mikez302 移除自动完成属性可以恢复自动完成功能,请参见http://jsfiddle.net/jefferyto/fhT9m/。也许您可以在投反对票之前尝试一下。 - Jeffery To
我尝试过,但它并没有禁用自动完成。我不知道为什么。看起来应该可以工作。 - Elias Zamaria
1
我测试了你的解决方案,但它表现得很奇怪。在文本框中输入并没有触发自动完成提示,但在文本框为空的情况下按下箭头键却会触发提示。这比我想象的更奇怪和复杂。很抱歉我之前给你的回答评价打了差评,我当时以为你没有理解我的问题。 - Elias Zamaria
@mikez302,你能否发布一个 jsFiddle,展示你所看到的行为? - Jeffery To
我想停止自动填充,这个答案解决了问题,但它是如何工作的? - Anas

4

不是很好的解决方案,但在Chrome 56上可以使用:

<INPUT TYPE="text" NAME="name" ID="name" VALUE=" ">
<INPUT TYPE="password" NAME="pass" ID="pass">

请注意值上的空格。然后:
$(document).ready(function(){
   setTimeout(() => $('#name').val(''),1000);
});

2
终于!我找到的唯一有效的东西。不错。 - AndrewLeonardi

2
这可能会有所帮助:https://dev59.com/1HE85IYBdhLWcg3wJQCt#4196465
if (navigator.userAgent.toLowerCase().indexOf("chrome") >= 0) {
    $(window).load(function(){
        $('input:-webkit-autofill').each(function(){
            var text = $(this).val();
            var name = $(this).attr('name');
            $(this).after(this.outerHTML).remove();
            $('input[name=' + name + ']').val(text);
        });
    });
}

在加载时,它似乎会查找所有带有自动填充功能的输入框,添加它们的outerHTML并删除原始输入框,同时保留值和名称(可以轻松更改以保留ID等)。

如果这样可以保留自动填充文本,您只需设置

var text = "";   /* $(this).val(); */

根据原始发布的表单,它声称可以保留自动完成功能。 :)

祝你好运!


这似乎保持了自动填充的启用状态。它只是防止输入框的背景变成黄色,就像自动填充通常会做的那样。 - Elias Zamaria

1

一个解决方案是使用空格字符自动填充输入框,并在聚焦时清除它们。

例如:http://nfdb.net/autofill.php

<!doctype html>
<html>
    <head>
        <title>Autofill Test</title>
        <script>
            var userfield;

            // After the document has loaded, manipulate DOM elements.
            window.addEventListener('load', function() {

                // Get the username field element.
                userfield = document.getElementById('user');

                // Listen to the 'focus' event on the input element.
                userfield.addEventListener('focus', function() {

                    // Checks if the value is the EM space character,
                    // and removes it when the input is recieves focus.
                    if (this.value == '\u2003') this.value = ''

                }, false);

                // Listen to the 'blur' event on the input element.
                // Triggered when the user focuses on another element or window.
                userfield.addEventListener('blur', function() {

                    // Checks if the value is empty (the user hasn't typed)
                    // and inserts the EM space character if necessary.
                    if (this.value == '') this.value = '\u2003';

                }, false);
            }, false);
        </script>
    </head>
    <body>
        <form method="GET" action="">
            <input id="user" name="username" type="text" value="&#8195;"/><br/>
            <input name="password" type="password" value=""/><br/>
            <input type="submit" value="Login">
        </form>
    </body>
</html>

这样可以阻止浏览器自动填充字段,但仍然允许它们自动完成。

这里有另一个例子,在页面加载后清除表单输入。这种方法的优点是输入框中从未有任何空格字符,缺点是自动填充的值可能会在几毫秒内可见。

http://nfdb.net/autofill2.php

<!doctype html>
<html>
    <head>
        <title>Autofill Test</title>
        <script>
            var userfield, passfield;

            // Wait for the document to load, then call the clear function.
            window.addEventListener('load', function() {

                // Get the fields we want to clear.
                userfield = document.getElementById('user');
                passfield = document.getElementById('pass');

                // Clear the fields.
                userfield.value = '';
                passfield.value = '';

                // Clear the fields again after a very short period of time, in case the auto-complete is delayed.
                setTimeout(function() { userfield.value = ''; passfield.value = ''; }, 50);
                setTimeout(function() { userfield.value = ''; passfield.value = ''; }, 100);

            }, false);
        </script>
    </head>
    <body>
        <div>This form has autofill disabled:</div>
        <form name="login" method="GET" action="./autofill2.php">
            <input id="user" name="username" type="text" value=""/><br/>
            <input id="pass" name="password" type="password" value=""/><br/>
            <input type="submit" value="Login">
        </form>
        <div>This form is untouched:</div>
        <form name="login" method="GET" action="./autofill2.php">
            <input name="username" type="text" value=""/><br/>
            <input name="password" type="password" value=""/><br/>
            <input type="submit" value="Login">
        </form>
    </body>
</html>

我愿意考虑这个,尽管我担心如果有人想实际输入“ ”作为值可能会导致问题。 - Elias Zamaria
1
您可以使用不同的空格字符,例如 EM 空格。我只是举了普通空格作为示例。 - Nimphious
1
我将继续为代码添加注释。如果您希望我对某些内容进行更详细的解释,请告诉我。 - Nimphious
我不确定我是否喜欢你的第二个解决方案。如果从服务器传来的代码中实际上有任何值在value属性中,那么它似乎会被擦除。我不想删除输入中的任何值,只想删除自动填充的输入。 - Elias Zamaria
这样做的缺点是,“空字段”验证,它通过将值与空值进行比较来工作,不会正常工作,对吧? - Miguel
显示剩余4条评论

1

最近我遇到了这个问题,由于我的字段可以被预填充,没有简单的解决方案,所以我想分享一个优雅的技巧,通过在准备事件中设置密码类型来解决。

创建输入字段时不要将其声明为密码类型,而是添加一个准备事件监听器来为您添加它:

function createSecretTextInput(name,parent){
    var createInput = document.createElement("input");
    createInput.setAttribute('name', name);
    createInput.setAttribute('class', 'secretText');
    createInput.setAttribute('id', name+'SecretText');
    createInput.setAttribute('value', 'test1234');

    if(parent==null)
       document.body.appendChild(createInput);
    else
        document.getElementById(parent).appendChild(createInput);

    $(function(){
        document.getElementById(name+'SecretText').setAttribute('type', 'password');
    });
};

createSecretTextInput('name', null);

http://jsfiddle.net/


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