Disabling Chrome Autofill
我在几个表单上遇到了chrome自动填充行为的问题。
表单中的字段都有非常常见和准确的名称,例如"email"、"name"或"password",并且它们还设置了
autocomplete标志已成功禁用autocomplete行为,在该行为中,当您开始键入时,值的下拉列表会出现,但不会更改chrome自动填充字段的值。
除了Chrome错误地填充了输入内容(例如,使用电子邮件地址填充了电话输入内容),这种行为是正常的。客户抱怨过这一点,因此它被证实是在多种情况下发生的,而不是我在本地机器上所做的某种结果。
我能想到的唯一的当前解决方案是动态生成自定义输入名,然后在后端提取值,但这似乎是解决这个问题的一个非常糟糕的方法。有没有任何标签或怪癖可以改变自动填充行为,可以用来解决这个问题?
对于新的Chrome版本,您只需将
从Chrome开发者那里得到了这个提示:https://bugs.chromium.org/p/chromium/issues/detail?ID=370363 C7
另外,不要忘记为不同的字段使用唯一的名称,以防止自动填充。
我刚刚发现,如果您有一个记住的站点用户名和密码,当前版本的chrome会自动将您的用户名/电子邮件地址填充到任何
旧解决方案
只需使用
如果密码元素位于
标记内,则需要在
open标记后立即将虚拟元素作为表单中的第一个元素。 如果密码元素不在
标记内,则在
open标记后立即将虚拟元素作为HTML页面中的第一个元素。
您需要在不使用css
1 | <input type="password" style="width: 0;height: 0; visibility: hidden;position:absolute;left:0;top:0;"/> |
这是我提出的解决方案,因为谷歌坚持要凌驾于人们似乎做的每项工作之上。
选项1-单击选择所有文本为用户(如
1 2 | <input type="text" name="email" class="focus-select" value="your@email.com"> <input type="password" name="password" class="focus-select" value="password"> |
号
下面是jquery:
1 2 3 | $(document).on('click', '.focus-select', function(){ $(this).select(); }); |
我真的看不到铬与价值观的冲突。那太疯狂了。所以希望这是一个安全的解决方案。
选项2-将电子邮件值设置为空格,然后将其删除假设您有两个输入,如email和password,将email字段的值设置为
如果用户出于某种原因没有javascript,请确保您修剪了他们的输入服务器端(您可能无论如何都应该这样做),以防他们不删除空间。
这是jquery:
1 2 3 4 5 | $(document).ready(function() { setTimeout(function(){ $('[autocomplete=off]').val(''); }, 15); }); |
。
我给
如果不将初始值设置为空格,则会导致chrome将输入保留为黄色,就像它已经自动填充了它一样。
选项3-隐藏输入把这个放在表格的开头:
1 2 | <!-- Avoid Chrome autofill --> <input name="email" class="hide"> |
CSS:
1 | .hide{ display:none; } |
。
确保保留HTML注释,这样其他开发人员就不会删除它!同时确保隐藏输入的名称是相关的。
在某些情况下,即使"自动完成"属性设置为"关闭",浏览器也会继续建议自动完成值。对于开发人员来说,这种意外的行为可能非常令人费解。真正强制不自动完成的技巧是为属性分配一个随机字符串,例如:
1 | autocomplete="nope" |
。
我发现将此添加到表单可防止Chrome使用自动填充。
1 | <input type="text" id="PreventChromeAutocomplete" name="PreventChromeAutocomplete" autocomplete="address-level4" /> |
在这里找到的。https://code.google.com/p/chromium/issues/detail?ID=468153αHC41
令人失望的是,Chrome决定比开发人员更清楚何时自动完成。有微软的感觉。
1 | <input readonly onfocus="this.removeAttribute('readonly');" type="text"> |
号
将readonly属性与onfocus事件一起添加到标记中,移除它可以修复此问题
对于用户名密码组合,这是一个容易解决的问题。Chrome启发式搜索模式:
1 | <input type="text"> |
。
然后:
1 | <input type="password"> |
只需通过使其无效来中断此过程:
1 2 | <input type="text"> <input type="text" onfocus="this.type='password'"> |
。
使用css text security:disc而不使用type=password。
HTML
1 2 3 4 5 6 7 8 9 | <input type='text' name='user' autocomplete='off' /> <input type='text' name='pass' autocomplete='off' class='secure' /> or <form autocomplete='off'> <input type='text' name='user' /> <input type='text' name='pass' class='secure' /> </form> |
。
CSS
1 2 3 4 | input.secure { text-security: disc; -webkit-text-security: disc; } |
Mike Nelsons提供的解决方案在Chrome 50.0.2661.102 M中不适用。只需添加一个具有display:none-set的相同类型的输入元素,就不再禁用本机浏览器的自动完成功能。现在需要复制要禁用自动完成功能的输入字段的名称属性。
此外,为了避免在表单元素中复制输入字段,您应该在未显示的元素上放置一个禁用项。这将阻止该元素作为表单操作的一部分提交。
1 2 3 | <input name="dpart" disabled="disabled" type="password" style="display:none;"> <input name="dpart" type="password"> <input type="submit"> |
。
如果您在保留占位符时遇到问题,但禁用了chrome自动填充,我找到了解决方法。
问题
HTML
1 2 3 | <input type="text" placeholder="name"> <input type="text" placeholder="email"> <input type="text" placeholder="street"> |
http://jsfidle.net/xmbvwfs6/1/
上面的例子仍然会产生自动填充的问题,但是如果你使用
解决方案
HTML
1 2 3 4 5 6 7 8 | <input type="text" required="required"> <label>Name</label> <input type="text" required="required"> <label>Email</label> <input type="text" required="required"> <label>Street</label> |
。
CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | input { margin-bottom: 10px; width: 200px; height: 20px; padding: 0 10px; font-size: 14px; } input + label { position: relative; left: -216px; color: #999; font-size: 14px; } input:invalid + label { display: inline-block; } input:valid + label { display: none; } |
。
http://jsfidle.net/mwshpx1o/1/
2016年,Google Chrome开始忽略
The tricky part here is that somewhere along the journey of the web autocomplete=off become a default for many form fields, without any real thought being given as to whether or not that was good for users. This doesn't mean there aren't very valid cases where you don't want the browser autofilling data (e.g. on CRM systems), but by and large, we see those as the minority cases. And as a result, we started ignoring autocomplete=off for Chrome Autofill data.
号
本质上说:我们更清楚用户想要什么。
当需要autocomplete=off时,他们打开了另一个bug来发布有效的用例。
我没有看到通过我的B2B应用程序自动完成连接的问题,但只有输入密码类型。
如果屏幕上有任何密码字段,即使是隐藏的,也会自动填充。为了打破这个逻辑,如果每个密码字段不打破您自己的页面逻辑,您可以将它放入自己的表单中。
1 2 3 4 5 | <input type=name > <form> <input type=password > </form> |
。
既然我们都有这个问题,我花了一些时间为这个问题编写了一个有效的jquery扩展。谷歌必须遵循HTML标记,而不是谷歌
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | (function ($) { "use strict"; $.fn.autoCompleteFix = function(opt) { var ro = 'readonly', settings = $.extend({ attribute : 'autocomplete', trigger : { disable : ["off"], enable : ["on"] }, focus : function() { $(this).removeAttr(ro); }, force : false }, opt); $(this).each(function(i, el) { el = $(el); if(el.is('form')) { var force = (-1 !== $.inArray(el.attr(settings.attribute), settings.trigger.disable)) el.find('input').autoCompleteFix({force:force}); } else { var disabled = -1 !== $.inArray(el.attr(settings.attribute), settings.trigger.disable); var enabled = -1 !== $.inArray(el.attr(settings.attribute), settings.trigger.enable); if (settings.force && !enabled || disabled) el.attr(ro, ro).focus(settings.focus).val(""); } }); }; })(jQuery); |
只需将它添加到/js/jquery.extends.js这样的文件中,并将其包含在jquery之后。加载文档时将其应用于每个表单元素,如下所示:
1 2 3 | $(function() { $('form').autoCompleteFix(); }); |
。
J处理测试
通过将
编辑:如果
这有两件事。Chrome和其他浏览器将记住以前为字段名输入的值,并根据这些值向用户提供自动完成列表(特别是,由于相当明显的原因,密码类型输入永远不会以这种方式记住)。您可以添加
但是,您有密码填充器。大多数浏览器都有自己的内置实现,还有许多第三方实用程序提供此功能。你不能停下来。这是用户自己选择保存这些信息以便稍后自动填写,并且完全超出了您的应用程序的影响范围和范围。
我真的不喜欢做隐藏的领域,我认为这样做会很快让人困惑。
在要停止自动完成的输入字段上,这将起作用。将字段设为只读,并在焦点上删除该属性,如下所示
1 | <input readonly onfocus="this.removeAttribute('readonly');" type="text"> |
这样做的目的是,首先必须通过选择字段来删除只读属性,此时很可能会填充自己的用户输入并弯起自动填充来接管。
根据chromium bug报告chrome不再尊重
唯一有效的解决方案是添加一个虚拟密码字段:
1 2 | <input type="password" class="hidden" /> <input type="password" /> |
不同的解决方案,基于WebKit。如前所述,只要chrome找到密码字段,它就会自动完成电子邮件。对于afaik,这与autocomplete=[无论什么]无关。
要避免这种情况,请将输入类型更改为文本,并以所需的任何形式应用WebKit安全字体。
1 2 3 4 | .secure-font{ -webkit-text-security:disc;} <input type ="text" class="secure-font"> |
从我看来,这至少和input type=password一样安全,它是复制和粘贴安全的。但是,通过删除删除星号的样式,它很容易受到攻击,当然,可以在控制台中将input type=password轻松更改为input type=text以显示任何自动填充的密码,因此它实际上是相同的。
以前由chrome缓存的值显示为下拉选择列表。可以通过autocomplete=off禁用此选项,当地址字段获得焦点时,chrome高级设置中显式保存的地址将弹出自动填充弹出窗口。可以通过autocomplete="false"禁用此选项,但它将允许chrome在下拉列表中显示缓存的值。
在输入HTML字段上,后面的两个都将关闭。
埃多克斯1〔8〕
为地址自动填充选择输入字段时,chrome将忽略那些没有前面的label html元素的输入字段。
为确保Chrome解析器忽略自动填充地址弹出窗口的输入字段,可以在标签和文本框之间添加隐藏按钮或图像控件。这将破坏为自动填充创建标签-输入对的chrome解析序列。分析地址字段时忽略复选框
chrome还考虑标签元素上的"for"属性。它可以用来中断chrome的解析序列。
这是一个肮脏的黑客-
您的元素位于此处(添加禁用的属性):
1 | <input type="text" name="test" id="test" disabled="disabled" /> |
然后在网页的底部放置一些javascript:
1 2 3 | setTimeout(function(){ document.getElementById('test').removeAttribute("disabled"); },100); |
。
请尝试以下适用于我的
1 2 3 4 | if ($.browser.webkit) { $('input[name="password"]').attr('autocomplete', 'off'); $('input[name="email"]').attr('autocomplete', 'off'); } |
。
我也面临同样的问题。下面是在Chrome上禁用自动填充用户名和密码的解决方案(仅用Chrome测试)
1 2 3 | <!-- 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"> |
而不是"这对我有用"的答案和其他看起来像完全黑客的答案…这是目前Chrome(和最新的规范)如何处理
https://developers.google.com/web/fundamentals/design-and-ui/input/forms/label-and-name-inputs?HL=EN
tldr:在输入上添加
另外,从表单中删除autocomplete属性
唯一适合我的方法是:(jquery是必需的)
1 2 3 4 5 | $(document).ready(function(e) { if ($.browser.webkit) { $('#input_id').val(' ').val(''); } }); |
。
尝试在值中空白:
1 2 | <input type="email" name="email" value=" "> <input type="password" name="password" value=" "> |
铬54.0.2840.59
在密码字段中添加
但是,正如sibbl指出的,这并不能阻止chrome在表单提交完成后要求您保存密码。从chrome 51.0.2704.106开始,我发现您可以通过添加一个不可见的伪密码字段来实现这一点,该字段还具有属性
1 2 | <input type="password" autocomplete="new-password" style="visibility:hidden;height:0;width:1px;position:absolute;left:0;top:0">` |
只有当我将宽度设置为非零值时,这才对我有效。感谢Tibalt和Fareed Namrouti提供的原始答案。
我的解决方案,因为上面没有一款在Chrome63及更高版本上有效。
我在我的站点上修复了这个问题,将有问题的输入元素替换为
1 2 | <p class="input" contenteditable="true"> </p> |
号
并在提交之前使用jquery填充隐藏字段。
但这是一个真正可怕的黑客所必需的一个错误的决定铬。
我终于找到了使用
我需要一些额外的字段才能正常工作,因为Chrome实际上填充了许多字段。我还需要用一种比展示更花哨的方式来隐藏这些领域:没有一个能真正起作用。
1 2 3 4 5 6 7 8 9 | <style>.stylish { position:absolute; top:-2000px; }</style> <input id="_____fake_email_remembered" class="stylish" tabindex="-1" type="email" name="email_autofill"/> <input id="_____fake_userName_remembered" class="stylish" tabindex="-1" type="text" name="userName_autofill"/> <input id="_____fake_firstName_remembered" class="stylish" tabindex="-1" type="text" name="firstName_autofill"/> <input id="_____fake_lastName_remembered" class="stylish" tabindex="-1" type="text" name="lastName_autofill"/> <input id="_____fake_phone_remembered" class="stylish" tabindex="-1" type="text" name="phone_autofill"/> <input id="_____fake_address_remembered" class="stylish" tabindex="-1" type="text" name="address_autofill"/> <input id="_____fake_password_remembered" class="stylish" tabindex="-1" type="password" name="password_autofill"/> <input id="_____fake_password_remembered2" class="stylish" tabindex="-1" type="password" name="passwordRepeated_autofill"/> |
最后我想我找到了一个不错的解决办法。更好地理解下拉菜单如何与Chrome一起工作有助于:)基本上,当您聚焦输入时,下拉菜单将显示;当您键入与Chrome内存中的内容匹配的条目时,当您生成鼠标按下事件时,下拉菜单将显示。记住这一点,当Chrome的默认名称为"name"、"email"等时,Chrome会对某些输入执行此操作。然后,我们只需在显示下拉列表时删除该名称,然后再将其添加回以下位置即可:)我想使用一种解决方案,只需添加"autocomplete off"属性即可使其正常工作。我认为这是有道理的。这是代码:
解决方案1
1 2 3 4 5 6 7 8 9 10 11 | jQuery('body').on('mousedown','[name="name"][autocomplete="off"], [name="email"][autocomplete="off"]',function(e){ e.stopImmediatePropagation(); if(typeof this.currentName =="undefined") this.currentName=jQuery(this).attr('name'); jQuery(this).attr('name',''); }); jQuery('body').on('blur','[autocomplete="off"]',function(e){ e.stopImmediatePropagation(); jQuery(this).attr('name',this.currentName); }); |
解决方案2(我最喜欢的一个)
我上面描述的解决方案将删除输入的名称,直到我们删除焦点(模糊),在那一刻,它将恢复原始名称。但可能会发生这样的情况:我们希望在键入时通过输入的name属性访问输入。这意味着我们需要在每次输入之后立即将名称放回原处。这个解决方案,基本上是基于第一个解决方案。在这种情况下,我们将在key down上添加名称,并将其放回keyup上。我认为这对于"自动完成"行为应该是什么的兼容性来说更为简洁。无论如何,这是代码:
1 2 3 4 5 6 7 8 9 10 11 | jQuery('body').on('mousedown keydown','[name="name"][autocomplete="off"], [name="email"][autocomplete="off"]',function(e){ e.stopImmediatePropagation(); if(typeof this.currentName =="undefined") this.currentName=jQuery(this).attr('name'); jQuery(this).attr('name',''); }); jQuery('body').on('blur keyup','[autocomplete="off"]',function(e){ e.stopImmediatePropagation(); if(typeof this.currentName !="undefined") jQuery(this).attr('name',this.currentName); }); |
号
Please notice that for Solution 1 and 2, I just took the cases where the input name is"name" and"email". For any other case where this attribute makes Chrome generate the dropdown you will have to add it in the selector for the mouse down event.
号
解决方案3
这个解决方案要混乱得多。我没有意识到,我们试图纠正的行为仅仅是基于那些带有特定名称的输入,如"姓名、电子邮件等"。这个解决方案的方法是在这种情况下,chrome会显示我们不知道先验的其他名称。这将是一个非常通用的解决方案。我不喜欢其他2个,基本上是因为当我们按下删除键时可能会有一个小的闪烁。我来解释一下。
我发现下拉列表是在第二次单击输入之后出现的,但在第一次将焦点集中在输入上时不会出现在第一次单击上。我为所有这些元素绑定了一个"mouse down"事件,在这个事件中,处理程序基本上检测到它是否已经聚焦在输入上,如果它检测到另一个"mouse down",则强制执行一个.blur(),然后在.focus()之后,防止第二次单击时的下拉。我希望,这很清楚,以防万一我使用的代码是:
1 2 3 4 5 6 7 | jQuery('body').on('mousedown','[autocomplete="off"]',function(e){ e.stopImmediatePropagation(); if(jQuery(this).is(':focus')) { jQuery(this).blur(); jQuery(this).focus(); } }); |
另一方面,为了防止在输入时下拉,以防它与chrome建议匹配…这有点棘手。我刚刚决定在用户输入时替换输入的默认行为。下拉列表在鼠标按下时评估输入,因此我防止了字母数字、空格等的默认行为。唯一的问题是命令、ctrl和delete。对于这个案例,我还必须在鼠标上方绑定一个事件。它允许前两种情况下的默认行为,因此您可以进行复制、粘贴或全选。在删除的情况下,我必须允许默认行为,但是如果删除字符后输入与chrome建议匹配,那么它再次显示下拉列表。在这种情况下,我不得不使用同样的模糊和聚焦技巧。我发现的唯一不便是,因为我们取消了keyup上的行为,而chrome试图在keydown上显示它,所以会有一个小的闪烁。不管怎样,这是我能做的最好的。可能需要在某一点过滤字符。我只是补充了一些现在更合理的条件。这是代码的第二部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | jQuery('body').on('keydown','[autocomplete="off"]',function(e){ e.stopImmediatePropagation(); var ctrlKey = 17,cmKey = 91; var charCode = e.which || e.keyCode; if(charCode!=16 && this.commandDown != true && this.ctrlDown != true && ((charCode>47 && charCode<58)||(charCode>64 && charCode<91)||(charCode>96 && charCode<123)||charCode==0 || charCode==32)){ e.preventDefault(); var charStr = String.fromCharCode(charCode); if(!e.shiftKey) charStr = charStr.toLowerCase(charStr); $(this).val($(this).val() + charStr); }else{ if (charCode == cmKey) this.commandDown = true; if (charCode == ctrlKey) this.ctrlDown = true; } }); jQuery('body').on('keyup','[autocomplete="off"]',function(e){ e.stopImmediatePropagation(); var allowed=[8];//Delete var ctrlKey = 17,cmKey = 91; var charCode = e.which || e.keyCode; if (charCode == cmKey) {this.commandDown = false}; if (charCode == ctrlKey) {this.ctrlDown = false}; if(allowed.indexOf(charCode)>=0 || (this.commandDown!=false && this.ctrlDown!=false)){ jQuery(this).blur(); jQuery(this).focus(); } |
。
正如我所说,这个解决方案要混乱得多。这是我第一次使用它,直到我意识到下拉列表只出现在某些输入名称中。
很抱歉写了这么多,我只是想确保一切都清楚。希望有帮助。
就像DVD弗朗哥说的,对我来说,只有在所有的领域里,它起作用了。所以我把这个jquery规则放在主.js文件的$(document.ready();函数中。
1 2 | $('form.no_autofill').attr('autocomplete','off'); $('.no_autofill input').attr('autocomplete','off'); |
Boom、Google Chrome和其他任何人都试图击败这一点。
我可以在2017年9月7日实现这一功能,但使用我的MVC视图中生成的随机字符串的FormCollection。
我将首先在登录页面的索引控制器中获取一个新的随机密钥,加密并创建一个完全唯一的随机字符串(我实际上使用了一个256位的密码器来执行此操作,以及一个唯一的密码器和身份验证密钥),然后在每个字符串的末尾附加纯文本"用户名"和"密码",以帮助我以后从重复中识别查看控制器的用户名和密码。您也可以将普通字符串更改为任何类型,只要您知道模式并且它是唯一的。
在我的视图中,然后我适当地使用这些变量,然后在响应的控制器中-通过FormCollection搜索并找到匹配的变量-然后使用该项的键值作为相应的用户名和密码进行适当的处理。
另一个我认为是含铬的问题是
有什么想法吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <style> @@font-face { font-family: 'password'; font-style: normal; font-weight: 400; src: url(https://jsbin-user-assets.s3.amazonaws.com/rafaelcastrocouto/password.ttf); } </style> <input type="text" name="@Model.UsernameRandomNameString" /> <input style="font-family: 'password'" type="text" name="@Model.PasswordRandomNameString" /> LogOnModel model = new LogOnModel() { UsernameRandomNameString = Cryptography.SimpleEncrypt("Username", UniqueGeneratorKey, UniqueGeneratorKey) +"Username", PasswordRandomNameString = Cryptography.SimpleEncrypt("Password", UniqueGeneratorKey, UniqueGeneratorKey) +"Password", }; |
我认为这是一个很好的解决方法,但是,嘿,它是有效的,而且我认为它也可以成为未来的证明,除非谷歌确定页面的URL中有关键字,然后适当地在任何输入字段的顶部添加它的愚蠢扩展-但这有点夸张。
我的解决方案取决于三件事:
首先,我们需要防止用户名和密码的自动完成,因此,最初我们将设置两个标志,i->username和j->passowrd,值为真,因此如果没有任何键,i和j都将为真。
在可能的情况下,字段屏蔽发生在服务器端,通过传递随机字符串,也可以很容易地使用客户端进行屏蔽。
这是代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | $(document).ready(function(){ i= true; //username flag j= true; // password flag $("#username{{$rand}}").keydown(function(e){ // {{$rand}} is server side value passed in blade view // keyboard buttons are clicked in the field i = false; }); $("#passowrd{{$rand}}").keydown(function(e){ // {{$rand}} is server side value passed in blade view // keyboard buttons are clicked in the field j = false; }); // Now we will use change event, $("#username{{$rand}}").change(function(){ if($(this).val() != ''){ //the field has value if(i){ // there is no keyboard buttons clicked over it $(this).val(''); // blank the field value } } }) $("#password{{$rand}}").change(function(){ if($(this).val() != ''){ // the same as username but using flag j if(j){ $(this).val(''); } } }) $("#sForm").submit(function(e){ // the id of my form $("#password-s").val($("#password{{$rand}}").val()); $("#username-s").val($("#username{{$rand}}").val()); // Here the server will deal with fields names `password` and `username` of the hidden fields $("#username{{$rand}}").val(''); $("#password{{$rand}}").val(''); }) }) |
。
以下是HTML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <form class="form-horizontal" autocomplete="off" role="form" id="sForm" method="POST" action="https://example.com/login"> <input type="hidden" name="password" id="password-s"> <input type="hidden" name="username" id="username-s"> <label for="usernameTDU3m4d3I5" class="col-md-3 control-label" style="white-space: nowrap">Username</label> <input id="usernameTDU3m4d3I5" placeholder="Username" autocomplete="off" style="border-bottom-left-radius: 10px; border-top-right-radius: 10px; font-family: fixed; font-size: x-large;" type="text" class="form-control" name="usernameTDU3m4d3I5" value="" required="required" autofocus=""> <label for="passwordTDU3m4d3I5" class="col-md-3 control-label" style="white-space: nowrap">Password</label> <input id="passwordTDU3m4d3I5" placeholder="Password" autocomplete="off" type="password" class="form-control" name="pa-TDU3m4d3I5" required=""> <button type="submit" class="btn btn-success"> <i class="fox-login" style="text-shadow: 0px 1px 0px #000">Login </button> </form> |
上述解决方案确实不会消除或阻止用户名和密码的自动完成,但会使自动完成变得毫无用处。也就是说,在不点击该字段上的键盘按钮的情况下,提交前该字段值将为空,因此将要求用户输入这些值。
更新我们也可以使用click event来防止用户自动完成列表出现在如下字段下:
1 2 3 4 5 6 7 8 9 10 11 12 | $("#username{{$rand}}").click(function(){ $(this).val(''); i = true; }) $("#password{{$rand}}").click(function(){ $(this).val(''); j = true; }) |
。限制:
此解决方案在触摸屏设备中可能无法按预期工作。
最终更新我已经完成了如下的干净实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | preventAutoComplete = true; // modifier to allow or disallow autocomplete trackInputs = {password:"0", username:"0"}; //Password and username fields ids as object's property, and"0" as its their values // Prevent autocomplete if(preventAutoComplete){ $("input").change(function(e){ // Change event is fired as autocomplete occurred at the input field trackId = $(this).attr('id'); //get the input field id to access the trackInputs object if (trackInputs[trackId] == '0' || trackInputs[trackId] != $(this).val()){ //trackInputs property value not changed or the prperty value ever it it is not equals the input field value $(this).val(''); // empty the field } }); $("input").keyup(function(e){ trackId = $(this).attr('id'); trackInputs[trackId] = $(this).val(); //Update trackInputs property with the value of the field with each keyup. }); } |
对于角度用户:
由于
autocomplete='off' (which prevents last cached suggestions).autocomplete = 'false | random-string' (which prevents autofill setting, since the 'random-string' is not known by the browser).
号
那么,如果禁用这两个恼人的建议,该怎么办呢?诀窍如下:
示例:
如果
1 2 3 4 5 6 7 8 9 10 11 | .hidden-fields { opacity: 0; float: left; height: 0px; width: 0px; } <input type="text" name="username" class="hidden-fields"> <input type="password" name="password" class="hidden-fields"> <your actual login fields></your actual login fields> |
号
在铬53.0.2785.92(64位)上,以下工作
1 2 | <input type="text" name="fake_username_remembered"> <input type="password" name="fake_password_remembered"> |
。
因此,显然最好的修复/黑客现在不再有效,再次。我使用的Chrome版本是49.0.2623.110 m,我的帐户创建表单现在显示了一个与表单无关的已保存用户名和密码。谢谢Chrome!其他的黑客看起来很恐怖,但这个黑客不那么恐怖…
为什么我们需要这些黑客工作是因为这些表单通常是帐户创建表单,即不允许填写密码的登录表单。帐户创建表单您不希望删除用户名和密码的麻烦。从逻辑上讲,这意味着在呈现时永远不会填充密码字段。所以我使用了一个文本框和一点javascript。
1 2 3 4 5 6 7 | <input type="text" id="password" name="password" /> 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. |
号
我发现这是可以接受的,因为用户在短时间内不会访问密码字段,如果该字段是密码字段,则将其发回服务器没有任何区别,因为不管怎样,它都是纯文本。
警告:如果像我一样,您使用与更新表单相同的创建表单,那么事情可能会变得棘手。我使用mvc.asp c,当我使用@html.passwordfo()时,密码不会添加到输入框中。这是件好事。我已经对此进行了编码。但是使用@html.textbox for()和密码将被添加到输入框中,然后作为密码隐藏。但是,当我的密码被散列时,输入框中的密码是散列密码,不应该再回发到服务器上-意外地保存散列密码对于试图登录的人来说是很痛苦的。基本上…如果使用此方法,请记住在呈现输入框之前将密码设置为空字符串。
我在"立即登录或注册"模式窗口中遇到了这个问题,如果用户已将其凭据保存到浏览器中,则会出现问题。登录和注册字段都已填充,因此我可以使用以下Angular JS指令清除它们:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | (function () { "use strict"; var directive = function ($timeout) { return { restrict:"A", link: function (scope, element, attrs) { $timeout(function () { element.val(""); $timeout(function () { element.val(""); }); }); } }; }; angular.module("app.directives").directive("autofillClear", ["$timeout", directive]); }()); |
它基本上与之前使用jquery的一些答案相同,但是是以一种角度完成的。
不幸的是,所有的解决方案似乎都不起作用。我可以用
1 2 3 | <!-- fake fields are a workaround for chrome autofill getting the wrong fields --> <input style="display:none" type="text" name="fakeusernameremembered"/> <input style="display:none" type="password" name="fakepasswordremembered"/> |
技术,但密码仍然填充。
自动完成功能已通过此技巧成功禁用。它起作用了!
[HTML]
1 | <input id="password_1" type="text" name="password"> |
[查询]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | $("#login_screen").on('keyup keydown mousedown', '#password_1', function (e) { let elem = $(this); if (elem.val().length > 0 && elem.attr("type") ==="text") { elem.attr("type","password"); } else { setTimeout(function () { if (elem.val().length === 0) { elem.attr("type","text"); elem.hide(); setTimeout(function () { elem.show().focus(); }, 1); } }, 1); } if (elem.val() ==="" && e.type ==="mousedown") { elem.hide(); setTimeout(function () { elem.show().focus(); }, 1); } }); |
。
除autocomplete="off"外,还必须将值设置为空(value=")才能使其正常工作。
我所做的是将输入type="text"更改为多行输入ie。
1 2 3 4 | overflow-x:hidden; overflow-y:hidden; vertical-align:middle; resize: none; |
代码的快速解释:overflow-x和-y隐藏将禁用文本框右侧的滚动按钮。垂直algin将使标签垂直居中与文本区域对齐,并且调整大小:无将禁用文本区域右下角的调整大小抓取器。
在消息中,这意味着文本区域将像文本框一样出现,但Chrome AutoFill关闭。
我试过上面提到的所有建议,但都没用。我使用的是google将自动完成功能放在指定的输入上,如果google放置自动完成功能列表上方有google chrome自动填充功能,那就很难看了。即使设置autocomplete="anything"也没用,因为autocomplete插件本身将此attr设置为"off",并且被chrome完全忽略。
所以我的解决办法是:
1 2 3 4 5 6 7 | var fixAutocomplete = window.setInterval(function(){ if ($('#myinput').attr('autocomplete') === 'false') { window.clearInterval(fixAutocomplete); } $('#myinput').attr('autocomplete', 'false'); }, 500); |
我的问题是Chrome会在引导程序自动完成界面上自动填充邮政编码,因为我会自动建议数据库中可能的值。
我必须做的事情:
- 将输入字段的
id 属性更改为"邮政编码"以外的内容 - 将输入字段的
autocomplete 值更改为false - 调用
$('#postcode_field').autocomplete(...) 之后,我必须用$('#postcode_field').prop('autocomplete', 'false'); 重置autocomplete属性,因为boostrap的autocomplete插件会自动将其更改为off 。
纯HTML解决方案:
(不需要javascript,不需要CSS,不需要隐藏输入)
1 2 3 | <form autoComplete="new-password" ... > <input name="myInput" type="text" autoComplete="off" id="myInput" placeholder="Search field" /> </form> |
。
笔记:
- 窗体不必是输入元素的直接父级
- 输入需要名称属性
我知道这并不完全相关,但这就是我所做的。自动填充的字段会引发一个"更改"事件,但前提是要尽早将其绑定到这些字段。
所以我把这个放在头部。
1 2 3 | $(document).ready(function(){ $('input').on('change',function(){$(this).val('')}) }); |
。
这对我很有用。
约宾何塞的回答给了我一个开始。以下是适合我的:
1 2 | <input type="password" name="password" id="password_fake" style="display:none;" /> <input type="password" name="password"/> |
确保没有autocomplete="off",这会破坏解决方案。
如果表单是通过javascript生成的,那么通过在输入中添加"display:none;"来隐藏它的方法对我来说不起作用。
因此,我把它们放在看不见的地方,使它们隐形:
1 2 | <input style="width:0;height:0;opacity:0;position:absolute;left:-10000px;overflow:hidden;" type="text" name="fakeusernameremembered"/> <input style="width:0;height:0;opacity:0;position:absolute;left:-10000px;overflow:hidden;" type="password" name="fakepasswordremembered"/> |
我的黑客测试在铬48:
由于chrome试图通过查看
对于
对于
1 | <span>Ci<span style="display:none">*</span>ty</span> |
完整工作示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <!DOCTYPE html> <html> <body> <form method="post" action="/register"> <label for="name">Name</label> <input id="name" type="text" name="name" /> <label for="email">Email</label> <input id="email" type="text" name="email" /> <label for="id1">City</label> <input id="id1" type="text" name="id1" /> <-- STILL ON :( <label for="id2">Ci<span style="display:none">*</span>ty</label> <input id="id2" type="text" name="id2" /> <-- NOW OFF :) </form> </body> </html> |
这些问题的其他解决方案对我来说都不管用。
唯一有效的想法是:
It removes"name" and"id" attributes from elements and assigns them
back after 1ms. Put this in document get ready.
号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | $(document).ready(function() { $('form[autocomplete="off"] input, input[autocomplete="off"]').each(function () { var input = this; var name = $(input).attr('name'); var id = $(input).attr('id'); $(input).removeAttr('name'); $(input).removeAttr('id'); setTimeout(function () { $(input).attr('name', name); $(input).attr('id', id); }, 1); }); }); |
号
为"用户名"字段输入值""(空白)。
1 | <input type = 'text' value = ' ' name = 'username' /> |
。
如果使用用户输入的值填充用户名,则在没有用户输入的值的情况下,使用代码输入""。
编辑:我还必须更改'username'字段,使其名称不是'username',例如'nameofuser'
如果使用symfony表单,那么如果属性是从twig模板应用而不是使用
使用此:
1 2 3 4 5 6 7 | .... ->add('field-name', TextType::class, array( 'attr' => array( 'autocomplete' => 'off' ) ) .... |
号
而不是:
1 2 3 | .... {{ form_widget(form.field-name, {'attr': {'autocomplete':'off'}}) .... |
号
1月20日Chrome更新
上述解决方案都不起作用,包括添加假字段或设置autocomplete=new password。是的,使用这些chrome将不会自动完成,但当您输入密码字段时,它将再次建议密码。
我发现,如果删除密码字段,然后在没有ID的情况下再次添加它,那么chrome不会自动填充它,也不会在输入时建议使用密码。
使用类获取密码值而不是ID。
对于火狐,仍然需要添加一个虚拟元素。
此解决方案还允许/禁止基于标志的自动完成:
HTML:
1 2 3 4 5 | <!-- form is initially hidden, password field has a dummy id and a class 'id' --> <form id="loginForm" style="display:none;"> <span>email:</span><input type="text" placeholder="Email" id="loginEmailInputID"/> <span>Password:</span><input class="loginPasswordInput" type="password" placeholder="Password" id="justForAutocomplete"/> </form> |
页面加载:
1 2 3 4 5 6 7 8 | function hideAutoComplete(formId) { let passwordElem=$('#'+formId+' input:password'), prev=passwordElem.prev(); passwordElem.remove(); prev.after($('<input type="password" style="display:none">'), passwordElem.clone().val('').removeAttr('id')); } if (!allowAutoComplete) hideAutoComplete('loginForm'); $('#loginForm').show(); |
。
当您需要密码时:
1 | $('.loginPasswordInput').val(); |
号
因为显示器没用了添加
1 2 | <input type="text" name="fakeusernameremembered"/> <input type="password" name="fakepasswordremembered"/> |
。
在隐藏溢出的分区内,最大宽度和最大高度为0px
所以它变成了:
1 2 | <input type="text" name="fakeusernameremembered"/> <input type="password" name="fakepasswordremembered"/> |
所有的解决方案都不适合我。最后,在拔了我的头发好几个小时后,我想出了这个解决方案来处理ReactJS。
在Firefox 54.0.1、Chrome 61.0.3163.100、Mac OS 10.13上测试
我保留了
前任:HTML:
埃多克斯1〔3〕
JS:
1 2 3 4 5 6 7 8 | setAttr2: function(e){ var value = e.target.value; if(value.length){ e.target.setAttribute('type', 'email') } else { e.target.setAttribute('type', 'text') } } |
。
我想把我的修复贴上去。发现你不能使用显示器:没有,所以我想出了一个快速和肮脏的解决方案,只是使假输入小,并把它移开视线。到目前为止都很好,直到他们再次打破它。
1 | <input id="FakePassword" type="password" style="float:left;position:relative;height:0;width:0;top:-1000px;left:-1000px;" /> |
使用chrome,如果你用一个标签包围一个输入,并在标签内,输入"street"、"address"或同时输入这两个词,它将忽略禁用自动填充的任何尝试。
1 | <label for="searchAddress" class="control-label"> Street Address <input type="text" class="form-control" name="searchAddress></label> |
Chrome检测标签中的关键字以确定输入类型。它也可能与其他关键词一起使用。
我的解决方案:
1 2 3 | $(function(){ $("form[autocomplete=off]").find('input').attr('autocomplete', 'false'); }); |
它在具有"autocomplete="off"的表单中的所有输入字段上设置属性"autocomplete="false"。
这适用于Chrome、Firefox和Safari。
你可以这样做。
1 2 3 4 | $(window).load(function() { var form = $('#fatherel .container-form').html().replace(/legend/ig, 'form') $('#fatherel .container-form').html(form) }); |
。
我尝试了很多解决方案,看起来谷歌的更新可能已经改变了,截至2017年1月,对我有效的解决方案是添加另一个输入,并在填充后隐藏它。
1 2 3 4 5 6 | <input type="text" id="phone_number" name="phone_number" value=""> <input type="text" id="dummy_autocomplete"> script type="text/javascript"> $('#dummy_autocomplete').hide(); |
。
我最后通过在输入字段中放入一个非重复变量来解决这个问题-我使用了php time(),如下所示:
1 | <input type="text" name="town['.time().']"> |
号
这主要是干扰安卓系统。我在服务器端所做的就是对输入名执行foreach循环-问题是,如果chrome识别出它将自动填充的name属性。
其他什么都不适合我。
这是我使用的最新解决方案。
1 | $('#email').prop('autocomplete', true); |