Html 禁用 Safari 自动填充用户名和密码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22661977/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 01:23:28  来源:igfitidea点击:

Disabling Safari autofill on usernames and passwords

htmlsecurityautocompletesafariautofill

提问by Jari

You might already know, that Safari has a nasty autofill bug where it fills email, username and password fields no matter if you set autocomplete="off"or not.

您可能已经知道,Safari 有一个令人讨厌的自动填充错误,无论您是否设置,它都会填充电子邮件、用户名和密码字段autocomplete="off"

Here's a basic form:

这是一个基本形式:

<form action="/" method="post">
    <p>
        <label>E-mail</label>
        <input type="text" name="email" value="" />
    </p>
    <p>
        <label>Password</label>
        <input type="password" name="password" value="" />
    </p>
</form>

...Safari autofills those fields on page load like it should, job well done!

...Safari 在页面加载时自动填充这些字段,做得很好!

If you put autocomplete="off"to the fields and/or the form element, Safari still autofills those fields:

如果您autocomplete="off"输入字段和/或表单元素,Safari 仍会自动填充这些字段:

<form action="/" method="post" autocomplete="off">
    <p>
        <label>E-mail</label>
        <input type="text" name="email" value="" autocomplete="off" />
    </p>
    <p>
        <label>Password</label>
        <input type="password" name="password" value="" autocomplete="off" />
    </p>
</form>

Even this doesn't work:

即使这不起作用:

<form action="/" method="post" autocomplete="off">
    <p>
        <label>E-mail</label>
        <input type="text" name="secretfield1" value="" autocomplete="off"/>
    </p>
    <p>
        <label>Password</label>
        <input type="password" name="secretfield2" value="" autocomplete="off" />
    </p>
</form>

...since Safari looks up those <label>elements if they contain words "E-mail", "Password" etc. and goes ahead with the autofill.

...因为 Safari 会查找<label>包含“电子邮件”、“密码”等字样的元素,并继续进行自动填充。

Aaaahhhhha!, I thought, and tried this:

Aaaahhhhha!,我想,并尝试了这个:

<form action="/" method="post" autocomplete="off">
    <p>
        <label>%REPLACE_EMAIL_TITLE%</label>
        <input type="text" name="%REPLACE_EMAIL_NAME%" value="" autocomplete="off"/>
    </p>
    <p>
        <label>%REPLACE_PASSWORD_TITLE%</label>
        <input type="password" name="%REPLACE_PASSWORD_NAME%" value="" autocomplete="off" />
    </p>
</form>

...and replace %TAGS% with the real names using JavaScript. Safari autofill kicks in. No matter if you set a 10 second timeout on the replacement.

...并使用 JavaScript 将 %TAGS% 替换为真实姓名。Safari 自动填充开始。无论您是否在替换时设置了 10 秒超时。

So, is this really the only option?

那么,这真的是唯一的选择吗?

<form action="/" method="post" autocomplete="off">
    <p>
        <label>That electronic postal address we all use, but can't write the title here because Safari fills this with YOUR information if you have autofill turned on</label>
        <input type="text" name="someelectronicpostaladdress" value="" autocomplete="off"/>
    </p>
    <p>
        <label>A set of characters, letters, numbers and special characters that is so secret that only you or the user you are changing it for knows, but can't write the title here because Safari sucks</label>
        <input type="password" name="setofseeecretcharacters" value="" autocomplete="off" />
    </p>
</form>

I hope not?

我希望不是?

UPDATE: @skithund pointed out in Twitter, that Safari is getting a 4.0.3 update, which mentions "Login AutoFill". Does anyone know if that update is going to fix this?

更新:@skithund 在 Twitter 中指出Safari 正在获得 4.0.3 更新,其中提到了“登录自动填充”。有谁知道这个更新是否会解决这个问题?

回答by Ian Boyd

The reason browsers are ignoring autocomplete=offis because there have been some web-sites that tried to disable auto-completing of passwords.

浏览器忽略的原因autocomplete=off是因为有一些网站试图禁用自动完成密码。

That is wrong.

那是错的。

And in July 2014 Firefox was the last major browser to finally implement the change to ignore any web-site that tries to turn off autocompleting of passwords.

2014 年 7 月,Firefox 是最后一个最终实施更改以忽略任何试图关闭自动完成密码的网站的主要浏览器。

One of the top user-complaints about our HTML Forms AutoComplete feature is “It doesn't work– I don't see any of my previously entered text.”When debugging such cases, we usually find that the site has explicitly disabled the feature using the provided attribute, but of course, users have no idea that the site has done so and simply assume that IE is buggy. In my experience, when features are hidden or replaced, users will usually blame the browser, not the website.

用户对我们的 HTML 表单自动完成功能的最大抱怨之一是“它不起作用 - 我没有看到我以前输入的任何文本。” 在调试此类情况时,我们通常会发现站点使用所提供的属性明确禁用了该功能,但当然,用户并不知道站点已这样做,而只是假设 IE 有问题。根据我的经验,当功能被隐藏或替换时,用户通常会责怪浏览器,而不是网站。

Any attempt by any web-site to circumvent the browser's preference is wrong, that is why browsers ignore it. There is no reason known why a web-site should try to disable saving of passwords.

任何网站试图绕过浏览器的偏好都是错误的,这就是浏览器忽略它的原因。没有理由知道为什么网站应该尝试禁用密码保存。

  • Chrome ignores it
  • Safari ignores it
  • IE ignores it
  • Firefox ignores it
  • Chrome 忽略它
  • Safari 忽略它
  • IE 忽略它
  • Firefox 忽略它

At this point, web developers typically protest “But I wouldn't do this everywhere– only in a few little bits where it makes sense!”Even if that's true, unfortunately, this is yet another case where there's really no way for the browser to tell the difference. Remember, popup windows were once a happy, useful part of the web browsing experience, until their abuse by advertisers made them the bane of users everywhere. Inevitably, all browsers began blocking popups, breaking even the “good” sites that used popups with good taste and discretion.

在这一点上,Web 开发人员通常会抗议“但我不会在任何地方都这样做 - 只在有意义的一小部分!” 即使这是真的,不幸的是,这又是另一种情况,浏览器真的无法区分。请记住,弹出窗口曾经是 Web 浏览体验中一个快乐、有用的部分,直到它们被广告商滥用使它们成为各地用户的祸根。不可避免地,所有浏览器都开始阻止弹出窗口,甚至破坏了使用具有良好品味和谨慎性的弹出窗口的“好”网站。

What if I'm a special snowflake?

如果我是特殊的雪花怎么办?

There are people who bring up a good use-case:

有些人提出了一个很好的用例:

I have a shared, public area, kiosk style computer. We don't want someone to (accidentally or intentionally) save their password so the next user could use it.

我有一台共享的公共区域信息亭式计算机。我们不希望有人(无意或有意)保存他们的密码,以便下一个用户可以使用它。

That does not violate the statement:

这并不违反声明:

Any attempt by any web-site to circumvent the browser's preference is wrong

任何网站试图绕过浏览器的偏好都是错误的

That is because in the case of a shared kiosk:

这是因为在共享信息亭的情况下:

  • it is not the web-serverthat has the oddball policy
  • it is the client user-agentthat has the oddball policy
  • 它不是具有奇怪政策的网络服务器
  • 它是具有奇怪策略的客户端用户代理

The browser(the shared computer) is the one that has the requirement that itnot try to save passwords.

浏览器(在共享计算机)是有要求的一个没有尝试保存密码。

The correct way to prevent the browserfrom saving passwords
is to configure the browserto not save passwords.

防止正确的方法浏览器从保存密码
是在配置浏览器不保存密码。

Since you have locked down and control this kiosk computer: you control the settings. That includes the option of saving passwords.

由于您已锁定并控制此自助服务终端计算机:您可以控制设置。这包括保存密码的选项。

In Chrome and Internet Explorer, you configure those options using Group Policies (e.g. registry keys).

在 Chrome 和 Internet Explorer 中,您可以使用组策略(例如注册表项)配置这些选项。

From the Chrome Policy List:

Chrome 政策列表

AutoFillEnabled

Enable AutoFill

Data type:Boolean (REG_DWORD)

Windows registry location:Software\Policies\Chromium\AutoFillEnabled

Description:Enables Chromium's AutoFill feature and allows users to auto complete web forms using previously stored information such as address or credit card information. If you disable this setting, AutoFill will be inaccessible to users. If you enable this setting or do not set a value, AutoFill will remain under the control of the user. This will allow them to configure AutoFill profiles and to switch AutoFill on or off at their own discretion.

自动填充已启用

启用自动填充

数据类型:布尔型 (REG_DWORD)

Windows 注册表位置:Software\Policies\Chromium\AutoFillEnabled

说明:启用 Chromium 的自动填充功能,并允许用户使用以前存储的信息(例如地址或信用卡信息)自动完成 Web 表单。如果禁用此设置,用户将无法访问自动填充。如果您启用此设置或不设置值,自动填充将保持在用户的控制之下。这将允许他们配置自动填充配置文件并自行决定打开或关闭自动填充。

Please pass the word up to corporate managers that trying to disable autocompleting of password is wrong. It is so wrong that browsers are intentionally ignoring anyone who tries to do it. Those people should stop doing the wrong thing.?

请告知公司经理,试图禁用自动完成密码是错误的。浏览器故意忽略任何尝试这样做的人是错误的。那些人应该停止做错事。?

Put it another way

换个方式说

In other words:

换句话说:

  • if the usersbrowser
  • mistakes "Please enter the name of your favorite maiden name's first color."for a new password
  • and the user
  • doesn't want theirbrowser
  • to update theirpassword,
  • then they
  • will click Nope
  • 如果用户浏览器
  • 错误“请输入您最喜欢的娘家姓的第一个颜色。” 新密码
  • 用户
  • 不想要他们的浏览器
  • 更新他们的密码,
  • 然后他们
  • 将单击

enter image description here

在此处输入图片说明

  • if i want to save my HIPPA password: that's my right
  • if i want to save my PCI password: that's my right
  • if i want to save the "new password for the user": that's my right
  • if i want to save the one-time-password: that's my right
  • if i want to save my "first color's favorite maiden"answer: that's my right.
  • 如果我想保存我的 HIPPA 密码:那是我的权利
  • 如果我想保存我的 PCI 密码:那是我的权利
  • 如果我想保存“用户的新密码”:这是我的权利
  • 如果我想保存一次性密码:那是我的权利
  • 如果我想保存我的“第一种颜色最喜欢的少女”答案:那是我的权利。

It's not your job to over-rule the user's wishes. It's their browser; not yours.

否决用户的意愿不是你的工作。这是他们的浏览器;不是你的。

回答by Richard perris

I had the same problem. And though my solution is not perfect, it seems to work. Basically, Safari seems to look for an input field with password and username and always tries to fill it. So, my solution was to add a fake username and password field before the current one which Safari could fill. I tried using style="display: none;"but that did not work. So, eventually, I just used style="position:absolute; top:-50px;"and this hid the input field out of sight and seemed to work fine. I did not want to use JavaScript but I guess you could hide it with JavaScript.

我有同样的问题。虽然我的解决方案并不完美,但它似乎有效。基本上,Safari 似乎在寻找带有密码和用户名的输入字段,并总是尝试填充它。因此,我的解决方案是在 Safari 可以填充的当前字段之前添加一个假的用户名和密码字段。我尝试使用,style="display: none;"但没有用。所以,最终,我只是使用了它style="position:absolute; top:-50px;",这将输入字段隐藏在视线之外,似乎工作正常。我不想使用 JavaScript,但我想你可以用 JavaScript 隐藏它。

Now Safari never autocompleted my username and password fields.

现在 Safari 从不自动完成我的用户名和密码字段。

回答by dsuess

Fix: browser autofill in by readonly-mode and set writable on focus

修复:浏览器通过只读模式自动填充并在焦点上设置可写

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

(focus = at mouse click and tabbing through fields)

(焦点 = 在鼠标单击和选项卡通过字段)

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

更新:Mobile Safari 在字段中设置光标,但不显示虚拟键盘。New Fix 像以前一样工作,但处理虚拟键盘:

<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/

现场演示https://jsfiddle.net/danielsuess/n0scguv6/

// UpdateEnd

// 更新结束

Explanation: Browser auto fills credentials to wrong text field?

说明:浏览器自动将凭据填充到错误的文本字段?

Ok, you just noticed that:

好的,你刚刚注意到:

Safari autofill kicks in. No matter [what the fields are named]@Jari

Safari 自动填充开始。无论[字段名称是什么]@Jari

and there's an assumption that:

并且有一个假设:

Safari seems to look for an input field with password and username and always tries to fill it@user3172174

Safari 似乎在寻找带有密码和用户名的输入字段,并总是尝试填充它@user3172174

Sometimes I notice this strange behavior on Chrome and Safari, when there are password fields in the same form.I guess, the browser looks for a password field to insert your saved credentials. Then it autofills usernameinto the nearest textlike-input field , that appears prior the password fieldin DOM (just guessing due to observation). As the browser is the last instance and you can not control it,

有时我会在 Chrome 和 Safari 上注意到这种奇怪的行为,当有相同形式的密码字段时我猜,浏览器会查找密码字段来插入您保存的凭据。然后它将用户名自动填充到最近的 textlike-input 字段中,该字段出现在 DOM 中的密码字段之前(只是由于观察而猜测)。由于浏览器是最后一个实例,您无法控制它,

sometimes even autocomplete=off would not prevent to fill in credentialsinto wrong fields, but not user or nickname field.

有时甚至 autocomplete=off 也不会阻止将凭据填写到错误的字段中,但不会阻止用户或昵称字段。

This readonly-fix above worked for me.

上面的这个只读修复对我有用。

回答by Vadizar

Adding the css to the input will hide the safari button pseudo-element and users will not be able to use autocomplete

将 css 添加到输入将隐藏 safari 按钮伪元素,用户将无法使用自动完成功能

input::-webkit-contacts-auto-fill-button, 
input::-webkit-credentials-auto-fill-button {
  visibility: hidden;
  pointer-events: none;
  position: absolute;
  right: 0;
}

回答by Eric McCormick

After scanning through Apple's Safari HTML pagesand not finding anythingon auto complete, I did some searching and thinking.

在扫描了Apple 的 Safari HTML 页面并且在自动完成时没有找到任何内容后,我进行了一些搜索和思考。

After reading a (mildly) related questionon Apple discussions, I remembered that the default is to not allow remembered passwords, etc (which can be enabled in iDevice system settings, or at the prompt). Since Apple has moved this feature out of the browser and into their (proprietary, i)OS (screen shots on this article), I believe they are ignoring the HTML form/field property entirely.

在阅读了有关Apple 讨论的(温和的)相关问题后,我记得默认是不允许记住密码等(可以在 iDevice 系统设置中或在提示下启用)。由于 Apple 已将此功能从浏览器移至其(专有的 i)操作系统(本文的屏幕截图),因此我相信他们完全忽略了 HTML 表单/字段属性。

Unless they change their mentality as to this feature, as I'm sure this is theirexpected behavior, on their locked down devices, I would work under the assumption that this isn't going away. This is probably different for native iOS apps. Definitely keep the form autocomplete="off" and hopefully they'll one day get back to the HTML5 standardfor the feature.

除非他们改变对此功能的心态,因为我确信这是他们预期的行为,在他们锁定的设备上,我会在假设这不会消失的情况下工作。对于原生 iOS 应用程序,这可能有所不同。绝对保留表单 autocomplete="off" 并希望他们有一天会回到 HTML5 标准的功能。

I know this doesn't include any work around, but I think if you come to terms with it being a non-browser 'feature' on iDevices, it makes sense (in an Apple kind of way).

我知道这不包括任何解决方法,但我认为如果您接受它是 iDevices 上的非浏览器“功能”,这是有道理的(以 Apple 的方式)。

回答by dontwakemeup

This question has already been successfully answered, but as of today's date, the solution didn't work for me without making some oddly particular changes - so I'm noting it here as much for my own reference if I decide to come back to it as for everyone else's.

这个问题已经得到成功回答,但截至今天,该解决方案在没有进行一些奇怪的特定更改的情况下对我不起作用 - 所以如果我决定回到它,我会在这里记录它作为我自己的参考至于其他人。

  • The fake input needs to be afterthe real email input in the dom.
  • The fake input requires a fake label.
  • The fake label cannot be absolutely positioned.
  • Can't use display, visibility or opacity to hide the fake elements.
  • 虚假输入需要在 dom 中的真实电子邮件输入之后
  • 假输入需要假标签。
  • 假标签不能绝对定位。
  • 不能使用显示、可见性或不透明度来隐藏假元素。

The only solution I found was to clip the visibility of the fake elements with overflow: hidden.

我找到的唯一解决方案是使用overflow: hidden.

<label for="user_email">Email</label>
<input autocomplete="off" type="text" value="[email protected]" name="user[email]" id="user_email">
<!-- Safari looks for email inputs and overwrites the existing value with the user's personal email. This hack catches the autofill in a hidden input. -->
<label for="fake_email" aria-hidden="true" style="height: 1px; width: 1px; overflow: hidden; clip: rect(1px, 1px, 1px, 1px)">Email</label>
<input type="text" name="fake[email]" id="fake_email" style="height: 1px; width: 1px; overflow: hidden; clip: rect(1px, 1px, 1px, 1px)" tab-index="-1" aria-hidden="true">

For the record, the particular case this hack came in useful for was one where an admin is editing the profile of other users and Safari was replacing the email of the user with the email of the admin. We've decided that for the small (but frustrating) amount of support requests that this Safari 'feature' creates, it's not worth maintaining a hack that seems to need to evolve as Safari tightens up on it, and instead provide support to those users on how to turn off autofill.

作为记录,这个黑客有用的特殊情况是管理员正在编辑其他用户的个人资料,而 Safari 正在用管理员的电子邮件替换用户的电子邮件。我们已经决定,对于这个 Safari 的“功能”创建的少量(但令人沮丧)的支持请求,不值得维护一个似乎需要随着 Safari 对其加强而发展的黑客,而是为这些用户提供支持关于如何关闭自动填充。

回答by Ben

I can't believe this is still an issue so long after it's been reported. The above solutions didn't work for me, as safari seemed to know when the element was not displayed or off-screen, however the following did work for me:

我不敢相信这在被报道后这么长时间仍然是一个问题。上述解决方案对我不起作用,因为 safari 似乎知道元素何时未显示或不在屏幕上,但是以下方法对我有用:

<div style="position:absolute;height:0px; overflow:hidden; ">
  Username <input type="text" name="fake_safari_username" >
  Password <input type="password" name="fake_safari_password">
</div>

Hope that's useful for somebody!

希望这对某人有用!

回答by S M

I have also been bitten by Safari's weird default autocomplete behaviour, but rather than completely disable it, I managed to make it work for me by following the guidelines at https://www.chromium.org/developers/design-documents/form-styles-that-chromium-understands.

我也被 Safari 奇怪的默认自动完成行为咬了一口,但我没有完全禁用它,而是按照https://www.chromium.org/developers/design-documents/form- 上的指南设法让它为我工作铬理解的样式

Specifically, I put autocomplete="username"on the username field and autocomplete="password-current"on the password field. This tells the browser which fields to autofill, rather than having it guess, and it fixed autocomplete for my use case.

具体来说,我把autocomplete="username"用户名字段和autocomplete="password-current"密码字段。这会告诉浏览器自动填充哪些字段,而不是让它猜测,并且它为我的用例修复了自动完成。

This approach works for both "email first" login forms (password field not immediately visible, eg Google login) as well as conventional login forms with both username and password fields visible.

这种方法适用于“电子邮件优先”登录表单(密码字段不立即可见,例如 Google 登录)以及用户名和密码字段都可见的传统登录表单。

回答by vendo

My issue:I have a section in an admin area that allows users to set all language values, some of which contain the words "password", "email", "email address" etc. I don't want these values to be filled with the user's details, they are for creating translations into another language. This is then a valid exception to the "circumvent the browser's preference" mentioned.

我的问题:我在管理区域中有一个部分允许用户设置所有语言值,其中一些包含“密码”、“电子邮件”、“电子邮件地址”等词。我不希望填充这些值使用用户的详细信息,它们用于创建另一种语言的翻译。这是所提到的“绕过浏览器的偏好”的有效例外。

My solution:I simply created alternate names:

我的解决方案:我只是创建了备用名称:

$name = str_replace('email','em___l',$name);
$name = str_replace('password','pa___d',$name);
<input type="text" name="<?=$name?>" id="<?=$name?>" />

Then when the form is posted:

然后当表单发布时:

foreach($_POST as $name=>$value) {
    $name=str_replace('em___l','email',$name);
    $name=str_replace('pa___d','password',$name);
    $_POST[$name]=$value;
}

This is the only method that worked for me.

这是唯一对我有用的方法。

回答by Fran?ois

The CSS display: nonesolutions mentioned here did not work for me (October 2016). I fixed this issue with JavaScript.

display: none这里提到的 CSS解决方案对我不起作用(2016 年 10 月)。我用 JavaScript 解决了这个问题。

I don't mind the browser remembering passwords, but wanted to prevent a bad autofill. In my case, a form with a password field and no associated username field. (User edit form in Drupal 7 site, where the password field is required only for some operations.) Whatever I tried, Safari would find a victim field for the username of the autofilled password (the field placed visually before, for instance).

我不介意浏览器记住密码,但想防止错误的自动填充。在我的例子中,一个带有密码字段但没有关联的用户名字段的表单。(Drupal 7 站点中的用户编辑表单,其中只有某些操作需要密码字段。)无论我尝试什么,Safari 都会为自动填充密码的用户名找到一个受害者字段(例如,该字段放置在视觉之前)。

I'm restoring the original value as soon as Safari does the autofill. I'm trying this only for the first 2 seconds after page load. Probably even lower value is OK. My tests showed the autofill happens around 250 ms after page load (though I imagine this number depends a lot on how the page is constructed and loaded).

一旦 Safari 执行自动填充,我就会恢复原始值。我仅在页面加载后的前 2 秒内尝试此操作。可能更低的值也可以。我的测试显示自动填充发生在页面加载后大约 250 毫秒(尽管我认为这个数字很大程度上取决于页面的构建和加载方式)。

Here's my JavaScript code (with jQuery):

这是我的 JavaScript 代码(使用 jQuery):

// Workaround for Safari autofill of the e-mail field with the username.
// Try every 50ms during 2s to reset the e-mail to its original value.
// Prevent this reset if user might have changed the e-mail himself, by
// detecting focus on the field.
if ($('#edit-mail').length) {
  var element = $('#edit-mail');
  var original = element.attr('value');
  var interval = setInterval(function() {
    if ($(document.activeElement).is(element)) {
      stop();
    } else if (element.val() != original) {
      element.val(original);
      stop();
    }
  }, 50);
  var stop = function() {
    clearTimeout(timeout);
    clearInterval(interval);
  }
  var timeout = setTimeout(function() {
    clearInterval(interval);
  }, 2000);
}