2019, Chrome 76, approach to autocomplete off

后端 未结 9 2213
忘掉有多难
忘掉有多难 2020-12-29 04:43

There are are few posts out there about this. You spend hours going through each answer, testing, reading comments, to find that there is no solution. What have you done in

9条回答
  •  猫巷女王i
    2020-12-29 04:58

    Disabling autofill: Set autocomplete attribute to a non-standard value, e.g. "nope".

    Disabling autocomplete: The autocomplete function stores field names and their values when a form is submitted. There's (almost, see note 1) nothing sensible to be done to prevent storage except setting autocomplete to "off"/"false" (see why). Unfortunately that's not an option as it would enable autofill.

    However it's possible to prevent retrieval of previous values by appending "!" to the field names, where is unique per page load (thus making field names unrecognizable).

    On the client side this can be achieved by something like the following line of javascript (upon page load):

    Array.prototype.slice.call(document.body.getElementsByTagName('INPUT'))
       .forEach(function(elt) { elt.name += '!' + new Date().getTime(); });
    

    On the server side the part (if any) starting at "!" should be dropped from variable names (upon receiving post variables).

    PS: this answer is an erratum to my earlier solution which is cleaner but wasn't sufficiently tested and - as gasman rightly pointed out - doesn't work for ordinary forms. This new solution was tested on Chrome Canary 79, does work, has relatively small impact and degrades nicely. Still, I feel guilty about publishing this hack and will feel even more guilty if I ever encounter it in real forms. It is *very* dirty.

    Note 1: the only way to prevent storage that does make sense is to not set the name attribute in the first place (or to unset it), which necessitates intercepting the submit event to post the data "manually" (using XMLHttpRequest). Since the question is about forms and this strategy bypasses the traditional form-mechanism I've not elaborated on that approach. It's a nicer solution though.


    Addendum: I decided to follow up on note 1 since I really dislike having a non-localized solution. Here's a localized version in vanilla JS that limits all impact to a single spot on the client side. Append it as a script to the document body or put it in the onload handler of the document.

    function disableInputSuggestions(form) { // note: code uses ECMA5 features 
        // tweak the inputs of form 
        var inputs = Array.prototype.slice.call(form.getElementsByTagName('INPUT'));
        var nonce = Date.now();
        inputs.forEach(function(input, i) { 
            input.autocomplete = 'nope'; // prevent autocomplete
            input.originalName = input.name || input.id; // to not let this code break form handling of inputs without names (browsers fallback to the id in that case)
            input.name = nonce + '_' + i; // prevent autofill (if you're willing to eliminate all input ids first, then clear the name instead)
        });
        // replace the default submit handler by a custom one 
        form.onsubmit = function(ev) {
            // get the form data using the original variable names
            var formData = new FormData();
            inputs.forEach(function(input) { formData.set(input.originalName, input.value); });
            // submit the form data using XMLHttpRequest (alternatively, use a helper form or temporarily undo the tweaks to form) 
            var submitter = new XMLHttpRequest();
            submitter.open(form.getAttribute('method'), form.getAttribute('action'));
            submitter.onreadystatechange = function() {
                if(submitter.readyState == 4 && submitter.status == 200) {
                    // handle the server response, here assuming the default form.target = "_self"  
                    document.open();
                    document.write(submitter.responseText);
                    document.close();
                }
            }
            submitter.send(formData);
            return false; // prevent submitting form
        }; 
    }
    disableInputSuggestions(document.forms.myForm); // assumed: the form has id = myForm
    

提交回复
热议问题