Forms 2019年,Chrome 76,接近自动完成关闭
关于这方面的帖子很少。你花了几个小时去检查每个答案,测试,阅读评论,发现没有解决方案。你在2019年做了什么,Chrome 76,可以用吗Forms 2019年,Chrome 76,接近自动完成关闭,forms,google-chrome,autocomplete,street-address,Forms,Google Chrome,Autocomplete,Street Address,关于这方面的帖子很少。你花了几个小时去检查每个答案,测试,阅读评论,发现没有解决方案。你在2019年做了什么,Chrome 76,可以用吗 autocomplete='nope' 这是Chrome 76当前的工作解决方案 更新,2020年1月:从Chrome 79开始,自动完成(如此处定义)似乎不再将Autocomplete=“一些未识别的值”视为等同于Autocomplete=“on”,因此Autocomplete=“nope”或类似功能现在可以有效地禁用自动完成和自动填充 更新,2020年
autocomplete='nope'
这是Chrome 76当前的工作解决方案 更新,2020年1月:从Chrome 79开始,自动完成(如此处定义)似乎不再将
Autocomplete=“一些未识别的值”
视为等同于Autocomplete=“on”
,因此Autocomplete=“nope”
或类似功能现在可以有效地禁用自动完成和自动填充
更新,2020年4月:他们再次更改了它。从Chrome 81开始,autocomplete=“一些无法识别的值”
在禁用自动完成机制方面不再有效。然而,Autofill现在似乎比以前保守多了——它仍然不符合规范(带有name=“email”
和autocomplete=“off”
的字段仍然会收到自动填充建议),但它不会在随机表单字段上提供虚假的地址片段。因此,我现在的建议是使用autocomplete=“off”
。如果您想在名为email
的字段上执行此操作,您可能运气不好:-(
TL,DR:autocomplete属性似乎没有设置可以可靠地关闭所有autocomplete下拉列表。然而,导致这种情况的情况非常复杂,值得记录,希望能够清除大量相互冲突的建议 当前(76.0.3809.132)版本的Chrome中存在两种不同的机制,我们称之为自动填充和自动完成(不一定是它们的官方名称): 自动填充 自动填写功能尝试使用浏览器设置中存储的地址信息填写表单。它可以通过下拉列表底部的“管理地址…”选项(或类似选项)来识别。此功能不支持
autocomplete=“off”
或autocomplete=“false”
,作为Chrome开发者的一项深思熟虑的决定
在年,zkoch提供了以下解决方法:
如果您确实想禁用自动填充,我们的建议如下:
这一点是利用autocomplete属性提供有效的,
字段的语义含义。如果遇到自动完成
我们无法识别的属性,我们不会尝试填充它
例如,如果CRM工具中有地址输入字段
如果你不想让Chrome自动填充,你可以赋予它语义
这意味着相对于你的要求是有意义的:例如。
autocomplete=“新用户街道地址”。如果Chrome遇到这种情况,它会
不会尝试自动填充该字段
这是尝试的解决方案的基础,例如autocomplete=“nope”
;自动填充机制将跳过它无法识别的autocomplete
属性值的任何字段
实现此决策的代码,用于记录:
自动完成
“自动完成”功能提供了此表单字段中以前提交的值的下拉列表。此下拉列表没有“管理地址…”选项。自动完成不支持Autocomplete=“off”
或Autocomplete=“false”
属性;任何其他值(包括“无效”值,如Autocomplete=“nope”
)将保持启用状态
结论
自动完成下拉列表不能通过autocomplete
下拉列表关闭;任何禁用自动填充的值都将使自动完成处于启用状态,反之亦然。任何认为自己找到了有效解决方案的人(通过autocomplete
或其他方法,如CSS破解)应该检查它是否对这两种机制都有效
不幸的是,要说服Chrome的开发人员这是一个失败的过程,这可能会是一场艰苦的斗争。Autofill的开发人员显然相信他们做出了一个有计划的决定来打破autocomplete=“off”
同时为web开发人员提供了一个替代方案;这个替代方案被打破了,原因比他们意识到的更微妙。从他们的角度来看,结果来自于心怀不满的开发人员,他们懒得跳过一个小圈子,更新他们的autocomplete=“off”
属性。在所有的噪音中,信息都没有通过:箍圈坏了。正如所解释的,必须禁用自动填充
和自动完成
功能,这在单个输入中似乎是不可能的。我找到的唯一有效解决方案是在输入上设置
autocomplete=“off”
,并在真正的输入之前添加隐藏的假输入,以愚弄autofill
,如下所示:
<input name="Fake_Username" id="Fake_Username" type="text" style="display:none">
<input name="Fake_Password" id="Fake_Password" type="password" style="display:none">
<input name="NameInput" id="NameInput" type="text" autocomplete="off">
*此答案不正确。我发布了一个更好(但更难看)的解决方案作为新答案,并保留了此答案,因为某些部分可能仍然有用。如果这不是处理stackoverflow错误答案的方法,请随意删除此答案* 考虑使用autocomplete=,其中每个字段和跨页面加载都是唯一的 例如,如果某个字段是在时间戳TS请求页面后创建的第N个字段,则可以将其选择为nope_u; 对自动完成的影响:由于是自动完成的自定义值,chromium不会激活自动完成功能(请参阅) 对自动填充的影响:chromium通过将其指纹与以前遇到的字段进行比较来识别字段(请参阅)。如果识别,它可能会提供一个记忆值列表。指纹包含autocomplete属性的值。由于没有两个nonce相等,因此无法识别任何字段 注:
- 与gasman的回复相比,此处使用的术语autocomplete和autofill被替换
- 应动态创建所有字段
Array.prototype.slice.call(document.body.getElementsByTagName('INPUT')) .forEach(function(elt) { elt.name += '!' + new Date().getTime(); });
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
// Désactivation de l'autocomplete des input text function setAutocomplete(val) { var E = document.getElementsByTagName('INPUT'); for (var i = 0 ; i < E.length ; i++) { if (E[i].name == 'txt_nom') { console.log('txt_nom', E[i]); } var type = E[i].type.toUpperCase(); if (E[i].autocomplete != '') { continue; } if (type == 'HIDDEN') { // } else if (type == 'NUMBER') { E[i].autocomplete = 'off'; } else if ((type == 'TEL') || (type == 'EMAIL') || (type == 'SEARCH')) { E[i].autocomplete = 'disabled'; } else { E[i].autocomplete = val; } } } // Exécution de diverses fonctions à la fin de chaque chargement window.addEventListener("load", function() { // Désactivation de l'autocomplete des input text setAutocomplete('off'); });
--HTML-- <input type="text" name="example" autocomplete="off"> --Javascript-- let elements = document.querySelectorAll('[autocomplete="off"]'); elements.forEach(element => { element.setAttribute("readonly", "readonly"); element.style.backgroundColor = "inherit"; setTimeout(() => { element.removeAttribute("readonly"); }, 500); })
<input type="text" name="firstname" autocomplete="<?= bin2hex(random_bytes(10)) ?>" />