Disable form autofill in Chrome without disabling

2019-01-06 10:35发布

问题:

This question already has an answer here:

  • Disabling Chrome Autofill 69 answers

How can we disable Chrome's autofill feature on certain <input>s to prevent them from being automatically populated when the page loads?

At the same time I need to keep autocomplete enabled, so the user can still see the list of suggestions by clicking on the input or typing in it. Can this be done?

EDIT: Feel free to use plain Javascript or jQuery if you feel it is necessary or you feel like it would make your solution simpler.

回答1:

Here's the magic you want:

    autocomplete="new-password"

Chrome intentionally ignores autocomplete="off" and autocomplete="false". However, they put new-password in as a special clause to stop new password forms from being auto-filled.

I put the above line in my password input, and now I can edit other fields in my form and the password is not auto-filled.



回答2:

A little late, but here's my fool proof solution useful for pages like the sign up/registration page where the user has to input a new password.

<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 will detect two password inputs and will not auto fill the password fields. However, the field id="password_fake" one will be hidden via CSS. So the user will only see one password field.

I've also added some extra attributes "x-autocompletetype" which is a chrome experimental specific auto fill feature. From my example, chrome will autofill in the first name, last name and email address, and NOT the password field.



回答3:

Fix: prevent browser autofill in

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

Update: Mobile Safari sets cursor in the field, but does not show virtual keyboard. New Fix works like before but handles virtual keyboard:

<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();  }" />

Live Demo https://jsfiddle.net/danielsuess/n0scguv6/

// UpdateEnd

Explanation Instead of filling in whitespaces or window-on-load functions this snippet works by setting readonly-mode and changing to writable if user focuses this input field (focus contains mouse click and tabbing through fields).

No jQuery needed, pure JavaScript.



回答4:

After a lot of struggle, I have found that the solution is a lot more simple that you could imagine:

Instead of autocomplete="off" just simply use autocomplete="false" ;)

Try this...

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


回答5:

I stumbled upon the weird chrome autofill behaviour today. It happened to enable on fields called: "embed" and "postpassword" (filling there login and password) with no apparent reason. Those fields had already autocomplete set to off.

None of the described methods seemed to work. None of the methods from the another answer worked as well. I came upon my own idea basing on Steele's answer (it might have actually worked, but I require the fixed post data format in my application):

Before the real password, add those two dummy fields:

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

Only this one finally disabled autofill altogether for my form.

It's a shame, that disabling such a basic behavior is that hard and hacky.



回答6:

I'm not able to get my Chrome to autofill automatically on page load to test this, but you can try adding autocomplete="off" to your fields, then removing the attribute on load:

$(window).load(function() { // can also try on document ready
    $('input[autocomplete]').removeAttr('autocomplete');
});


回答7:

This might help: https://stackoverflow.com/a/4196465/683114

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

It looks like on load, it finds all inputs with autofill, adds their outerHTML and removes the original, while preserving value and name (easily changed to preserve ID etc)

If this preserves the autofill text, you could just set

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

From the original form where this was posted, it claims to preserve autocomplete. :)

Good luck!



回答8:

One solution would be to auto-fill the inputs with whitespace characters, and have them clear on focus.

Example: 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>

This should stop the browser from auto-filling the fields, but still allow them to auto-complete.

Here's another example that clears the form inputs after the page loads. The advantage of this method is that the inputs never have any whitespace characters in them, the disadvantage is that there's a small possibility that the auto-filled values may be visible for a few milliseconds.

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>


回答9:

I was recently faced with this problem, and with no simple solution since my fields can be prepopulated, I wanted to share an elegant hack I came up with by setting password type in the ready event.

Don't declare your input field as type password when creating it, but add a ready event listener to add it for you:

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/



回答10:

autocomplete="off" on the input now working on Chrome V44 (and Canary V47)



回答11:

A bit late to the party... but this is easily done with some jQuery:

$(window).on('load', function() {
    $('input:-webkit-autofill').each(function() {
        $(this).after($(this).clone(true).val('')).remove();
    });
});

Pros

  • Removes autofill text and background color.
  • Retains autocomplete on field.
  • Keeps any events/data bound to the input element.

Cons

  • Quick flash of autofilled field on page load.


回答12:

var fields = $('form input[value=""]');
fields.val(' ');
setTimeout(function() {
    fields.val('');
}, 500);


回答13:

Chrome password manager is looking for input elements with type="password" and fill in saved password. It also ignores autocomplete="off" property.

Here is fix for latest Chrome (Version 40.0.2181.0 canary):

<input name="password">

JS:

setTimeout(function() {
    var input = document.querySelector("input[name=password]");
    input.setAttribute("type", "password");
}, 0)


回答14:

Easiest solution, provide a value of ' ' for the username field (which you can still call 'username').

If the value can be populated by user-inputted values, as is usually the case for a form that you are validating, provide a value of ' ' when it is not already set. In PHP,

if(trim($username) == ''){$username = ' ';}

<input type='text' value = '$username' name = 'Username' />

I actually think autocompletion for username and password effectively gifts access to all your accounts to anyone who accesses your computer, regardless of how obscure your passwords are...



回答15:

My solution is based on dsuess user solution, which didn't work in IE for me, because I had to click one more time in the textbox to be able to type in. Therefore I adapted it only to Chrome:

$(window).on('load', function () {
    if (navigator.userAgent.indexOf("Chrome") != -1) {
        $('#myTextBox').attr('readonly', 'true');
        $('#myTextBox').addClass("forceWhiteBackground");
        $('#myTextBox').focus(function () {
            $('#myTextBox').removeAttr('readonly');
            $('#myTextBox').removeClass('forceWhiteBackground');
        });
    }
});

In your css add this:

.forceWhiteBackground {
    background-color:white !important;
}


回答16:

This far I've found this one is working, having to set a Timeout of 1ms for the action to complete after chrome's auto-filling ..

$(window).on('load', function() {
    setTimeout(function(){
        $('input[name*=email],input[name*=Password]').val('-').val(null);
    },1);
});

I'm wondering if there's any way of attaching this function to chrome self-completion firing, or even, redeclaring it



回答17:

Here's the latest solution I've discovered. This stops Google filling the fields out and highlighting them yellow before you've even typed anything. Basically, if you put "display:none" on the field Google is smart enough to ignore it and move to the next field. If you put "visibility:hidden" though it counts it as a field in the form which seems to interfer with it's calculations. No javascript needed.

<form method='post'>
    <input type='text' name='u' size='16'/>
    <input type='password' name='fake' size='1' style='width:1px;visibility:hidden'/><br />
    <input type='password' name='p' size='16'/>
</form>


回答18:

I don't like to use setTimeout in or even have strange temporary inputs. So I came up with this.

Simply change your password field type to text

<input name="password" type="text" value="">

And when the user focus that input change it again to password

$('input[name=password]').on('focus', function (e) {
    $(e.target).attr('type', 'password');
});

Its working using latest Chrome (Version 54.0.2840.71 (64-bit))



回答19:

Not a beautiful solution, but worked on Chrome 56:

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

Note a space on the value. And then:

$(document).ready(function(){
   setTimeout("$('#name').val('')",1000);
});


回答20:

Autofill works with name attribute of the input, so if you set a name for an input like "firstname", chrome will fill it.

If you want to disable it, use an odd name like "supermanname".

Javascript can't solve your problem.

Second solution: You can make your inputs hidden with the same names, and set their values with other inputs. I simplified the Js with jQUery.

<form action="handlerfile.php" method="post">
<input type="text" id="1" onclick="$("#2").val($("#1").val())"/>
<input type="hidden" name="username" id="2">
</form>


回答21:

You better use disabled for your inputs, in order to prevent auto-completion.

<input type="password" ... disabled />