【问题标题】:How to disable auto-fill in Safari 7如何在 Safari 7 中禁用自动填充
【发布时间】:2014-05-14 02:39:53
【问题描述】:

我正在尝试找到一种方法来使 Safari 7(使用版本 7.0.2、7.0.3 测试)尊重 autocomplete="off" 属性。无论我尝试什么,它都会继续自动填充。

这是我们设置新用户的管理页面之一的问题。我们的用户不断使用自己的用户名/密码进行保存。

这是我们正在使用的表单的缩写版本。我尝试将字段重命名为“xxu”和“xxp”,但自动填充似乎读取了标签标题。我已经用各种不同的标签愚弄了,但它仍然会以某种方式触发自动填充。

<form novalidate autocomplete="off">
     <div class="control-group">
          <label class="control-label">Username</label>
          <div class="controls">
               <input type="text" name="xxu" autocomplete="off" required="required">
        </div>
     </div>
     <div class="control-group">
          <label class="control-label">Username</label>
          <div class="controls">
               <input type="password" name="xxp" autocomplete="off" required="required">
        </div>
     </div>
</form>

我在 Apple 的网站上找到了描述此问题的这篇文章。 https://discussions.apple.com/message/25080203#25080203

有人知道在 Safari 7 中禁用自动填写表单的任何其他方法吗? (啊,这是我们对 IE 的期望)

感谢您的帮助。

【问题讨论】:

  • +1 我遇到了同样的问题。 Safari 7.02 不尊重autocomplete="off"。任何用户帐户编辑都非常令人沮丧和 UX 噩梦!
  • 一件事,如果您没有在该字段上设置 ID 或 NAME 属性,它不会自动填充密码字段。所以我想如果你真的需要。您可以有一个名为“密码”的隐藏字段和一个&lt;input type="password"&gt;,然后 JS 侦听对该字段的更改并将它们放入隐藏字段。我知道您不会认为这是一个答案,但是:P 我认为这实际上是不可能的。我有一个“金额”字段被填充,就好像它是用户名/电子邮件一样-.-
  • Dominic - 谢谢,我已经很绝望了,我可以尝试一下……呃,这真是一团糟。
  • 可以通过JS试试吗? stackoverflow.com/questions/582244/…
  • 谢谢,这是一个非常好的链接,有很多想法——我没见过那个。我可以轻松地换掉标签和字段名称,我只需要弄清楚是什么触发了自动填充 - 我认为它是标签名称。我会做更多的工作并在这里写回。

标签: html safari


【解决方案1】:

上面给出的解决方案对我不起作用。经过调查,我可以评估 Safari 启用自动填充的决定取决于以下因素:

  • 输入的“id”属性是否包含“name”?
  • 输入的“name”属性是否包含“name”?
  • 输入的标签是否包含“名称”?

然后我可以使用以下代码禁用 Safari 的自动填充功能,为了方便起见,我将其包装到一个 jQuery 插件中:

$(document).ready(function () {
	$('input').disableAutoFill();
});

(function($) {

	$.fn.disableAutoFill = function() {

		"use strict";

		var self = {

			/**
			 * Disable autofill for one input
			 * @param {Object} $input jQuery element
			 */
			disableAutoFill: function($input) {
				if (self.isBrowser('safari')) {
					self.alterLabel($input);
					self.alterName($input);
					self.alterId($input);
				}
				$input.attr('autocomplete', 'off');
			},

			/**
			 * Change input's name
			 * Make sure Safari wont detect the word "name" in the name attribute
			 * otherwise Safari will enable autofill
			 * @param {Object} $input jQuery element
			 */
			alterName: function ($input) {
				$input.attr('data-original-name', $input.attr('name'));

				// Find unique name attribute value
				var new_name = false;
				var iteration = 0;
				while (iteration < 10 && !new_name) {
					new_name = self.random();
					if (self.checkAttributeExists('name', new_name)) {
						new_name = false;
					}
				}

				if (new_name) {
					$input.attr('name', new_name);
					self.setFormSubmitHandler($input);
				}
			},

			/**
			 * Change input's id
			 * Make sure Safari wont detect the word "name" in the id attribute
			 * otherwise Safari will enable autofill
			 * @param {Object} $input jQuery element
			 */
			alterId: function ($input) {
				$input.attr('data-original-id', $input.attr('id'));

				// Find unique id attribute value
				var new_id = false;
				var iteration = 0;
				while (iteration < 10 && !new_id) {
					new_id = self.random();
					if (self.checkAttributeExists('id', new_id)) {
						new_id = false;
					}
				}

				if (new_id) {
					$input.attr('id', new_id);
					self.setFormSubmitHandler($input);
				}
			},

			/**
			 * Reset input's name and id to its initial values before submitting the form
			 * @param {Object} $input jQuery element
			 */
			setFormSubmitHandler: function ($input) {
				var $form = $input.closest('form');
				if ($form.length > 0) {
					$form.submit(function() {
						var id = $input.attr('data-original-id');
						if (id) {
							$input.attr('id', id);
						}
						var name = $input.attr('data-original-name');
						if (name) {
							$input.attr('name', name);
						}
					});
				}
			},

			/**
			 * Make sure Safari wont detect the word "name" in the label
			 * otherwise Safari will enable autofill
			 * @param {Object} $input jQuery element
			 */
			alterLabel: function ($input) {
				var $label = self.findLabel($input);
				if ($label && $label.length > 0) {
					var text = $label.text();
					var array = text.split('');
					text = array.join('<span></span>');
					$label.html(text);
				}
			},

			/**
			 * Find label element of an input
			 * see http://stackoverflow.com/questions/4844594/jquery-select-the-associated-label-element-of-a-input-field
			 * @param $input
			 * @returns {*}
			 */
			findLabel: function ($input) {
				var $label = $('label[for="'+$input.attr('id')+'"]');

				if ($label.length > 0) {
					return $label;
				}
				var $parentElem = $input.parent();
				var $parentTagName = parentElem.get(0).tagName.toLowerCase();

				if ($parentTagName == "label") {
					return $parentElem;
				}
				return null;
			},

			/**
			 * Generate a random string
			 * @returns {string}
			 */
			random: function () {
				var text = '';
				var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
				for (var i=0; i < 5; i++) {
					text += possible.charAt(Math.floor(Math.random() * possible.length));
				}
				return text;
			},

			/**
			 * Check if there is an existing DOM element with a given attribute matching a given value
			 * @param {string} attributeName
			 * @param {string} attributeValue
			 * @returns {boolean}
			 */
			checkAttributeExists: function (attributeName, attributeValue) {
				return $('['+attributeName+'='+attributeValue+']').length > 0;
			},

			/**
			 * Detect current Web browser
			 * @param {string} browser
			 * @returns {boolean}
			 */
			isBrowser: function (browser) {
				// http://stackoverflow.com/questions/5899783/detect-safari-using-jquery
				var is_chrome = navigator.userAgent.indexOf('Chrome') > -1;
				var is_explorer = navigator.userAgent.indexOf('MSIE') > -1;
				var is_firefox = navigator.userAgent.indexOf('Firefox') > -1;
				var is_safari = navigator.userAgent.indexOf("Safari") > -1;
				var is_opera = navigator.userAgent.toLowerCase().indexOf("op") > -1;
				if ((is_chrome)&&(is_safari)) {is_safari=false;}
				if ((is_chrome)&&(is_opera)) {is_chrome=false;}

				if (browser === 'chrome') {
					return is_chrome;
				}
				if (browser === 'explorer') {
					return is_explorer;
				}
				if (browser === 'firefox') {
					return is_firefox;
				}
				if (browser === 'safari') {
					return is_safari;
				}
				if (browser === 'opera') {
					return is_opera;
				}
				return false;
			}

		};

		self.disableAutoFill(this);

		return this;
	};



}(jQuery));

您也可以下载或查看文件here

【讨论】:

  • 不错的技巧。可惜我们不得不使用这样的技巧。
【解决方案2】:

我使用了一个随机数并将其合并到每个字段名称中,这样浏览器就永远无法识别该字段的名称。

【讨论】:

  • 我喜欢这个简单的解决方案。谢谢。
  • 这个很聪明,我也很喜欢。但是它在 IE 和 Safari 中对我不起作用。实际上,我在 IE 和 Safari 中没有找到任何适合我的解决方案。 ╮(╯_╰)╭
【解决方案3】:

遇到了同样的问题,并尝试了前面提到的前两个 HTML/CSS 解决方案。

它们对我(或 Safari 9.0.3 :) 不起作用,所以我实施了这样的解决方案

<div style="overflow: hidden;width: 0px;height: 0px;">
  <input id="password" type="password" name="password" />
</div>

在实际的表单输入字段之上。

在 OS X El Capitan 上运行的 Safari、Firefox (44.0.2) 和 Chrome (48.0.2564.109) 上测试。

【讨论】:

  • 您能否提供有关您的实施的更多信息?我刚刚使用相同的浏览器测试了您的解决方案,但它不起作用。我会很感激。提前致谢
  • 嗨,我在 JSF 密码更改表单中使用了这个普通的 sn-p:&lt;h:form&gt; &lt;div style="overflow: hidden;width: 0px;height: 0px;"&gt; &lt;input id="password" type="password" name="password" size="35" /&gt; &lt;/div&gt; &lt;p:password id="password0" value="#{bean.oldPassword}" size="35" autocomplete="off"&gt; &lt;f:validateRequired /&gt; &lt;/p:password&gt; &lt;!-- ... --&gt; &lt;/h:form&gt;
【解决方案4】:

我找到了一种更快、更简单的方法来避免表单自动完成。它适用于 Mac 上的 FF 27、Chrome 36 和 Safari 7.0.5。我还没有在其他操作系统上测试过。

我只是将一个假字段作为我的表单中的第一个位置,不需要标签或 id 和名称属性。例如,我用内联样式和 voilà!

隐藏了它
<input type="password" style="display: none">

我的表单中的电子邮件和密码字段按预期填充了数据库中的值,并且不再自动完成。

说实话,我也不喜欢这个解决方案...我很想找到一个兼容的标准解决方案,但似乎 autocomplete="off" 不再起作用了。

【讨论】:

  • 唉,这个解决方案不适用于 Mac 上的 Safari 7.0.6。电子邮件仍会自动填充。
  • 也许这与 Safari 版本无关,因为我在 7.0.6 中测试过,它仍然可以正常工作。
  • 这可能只是不同的情况。在我的示例中,我有一个登录表单(我想要自动填充)和一个添加新用户的对话框(我当然不希望新用户的电子邮件替换为登录用户的电子邮件)。只要我在第二个表单中有一个可见 &lt;input type="password"&gt;,电子邮件总是在这里自动填充。
  • 哇!我不知道该怎么想。这正是我的情况......我的登录表单有电子邮件和密码字段,就像你的情况一样,我有另一个表单来添加/编辑用户,其中包含可见的电子邮件和密码字段。就我而言,在它们上方添加 additional 解决了问题。对不起!
  • 在我的例子中,添加 style="display: none" 使 Safari 忽略该字段并自动填充电子邮件。最后我决定在添加新用户的表单中使用input type="text" 而不是input type="password"。这停止了​​自动填充。
【解决方案5】:

我采用了一种更简单的解决方案,适合我们在管理员维护用户帐户并偶尔设置密码的情况下,只需将用户的密码输入类型更改为:

&lt;input type="text" name="password" /&gt;

简单但有效。

【讨论】:

  • 这也是我们最终做的事情 - 管理员可以查看他们在只写字段上输入的内容。感谢您的提示。
  • 请。从安全角度来看,这不是正确的解决方案。
【解决方案6】:

我采用了 @Skurpi 提出的 douchebag_safari 方法的简化变体。它只是 HTML,位于我的表单底部。

<!-- http://stackoverflow.com/questions/22817801/how-to-disable-auto-fill-in-safari-7 -->
<div class="douchebag_safari" style="left: -9999px; position: fixed; width: 1px;">
    <input type="password">
</div>

【讨论】:

  • 这确实有效,但真是个 hack。什么**苹果??我不敢相信需要这种 kluge 工作只是让 Safari 做 HTML 表单字段应该能够做的事情。
【解决方案7】:

我尝试了所有方法,让它正常工作,然后更高版本的 Safari 再次破坏了我的网站。我即将尝试额外的表单字段(感谢 Skurpi)。同时,这是我的新解决方案(在 PHP 中)

if(strpos($_SERVER['HTTP_USER_AGENT'],'Safari') !== false)
{
?>
    <div style="background:#ffff66;border:1px solid #ff9900;font-size:1.5em;padding:1em;">
        The Safari browser has a known bug: autocomplete replaces required data in our form with incorrect values. Unfortunately this may prevent you from adding products to the shopping cart. <br /><br />Please try a different browser or go to your browser settings and turn off autocomplete and refresh the page.
    </div>
<?php
}

如果有足够多的网站这样做,也许 Safari 团队会得到提示并修复他们的浏览器以遵守 autocomplete="off" 属性。

【讨论】:

    【解决方案8】:

    我们最近遇到了同样的问题。最重要的是,我们在 onBlur 上对表单进行了 AJAX 验证。出于某种奇怪的原因,这会触发 safari 再次自动填充我们的电子邮件输入字段。因此,每次您填写所需的电子邮件时,Safari 都会填写它喜欢的电子邮件。无法通过我们的表单。

    我们的解决方案

    几乎要打破 Safari(和 Chrome)的自动填充算法。

    HTML:

    <div class="douchebag_safari">
        <input class="js-clear_field" tabindex="-1" name="e-mail" type="email">
        <input class="js-clear_field" tabindex="-1" name="Ecom_User_Password" type="password">
    </div>
    

    CSS:

    .douchebag_safari {
        position: fixed;
        width: 1px;
        left: -50px;
    }
    .douchebag_safari input {
        width: 1%;
    }
    

    JS:

    $('#form').on('submit', function () {
        "use strict";
        $('.js-clear_field').attr('disabled', 'disabled');
    }
    

    它的要点是: 我们在 Safari 的自动填充算法中放置了电子邮件和密码类型的输入字段,其名称将在 Safaris 自动填充算法中排名更高(或相同?),并将它们隐藏在屏幕之外。 OnSubmit,这些字段将被禁用,因此将被排除在 POST 到我们的后端。

    缺点是用户不会在我们的表单上自动完成,但我们认为在我们的案例中这是值得的。

    注意(假设您关心):禁用 Javascript 的用户仍会在他们的 POST 中包含这些字段。根据您的设置,您需要允许这两个字段进入您的后端以防止错误。出于安全原因,请确保您不对这些字段进行任何操作!

    作为奖励,这解决了 Chrome (35) 假设密码字段上方的输入字段是用户名的错误。在我们的例子中,它是一个数字字段,提供了奇怪的用户体验和错误。

    【讨论】:

      【解决方案9】:

      你可以使用这个javascript代码:

      if (document.getElementsByTagName) {
      
      var inputElements = document.getElementsByTagName(“input”);
      
      for (i=0; inputElements[i]; i++) {
      
      if (inputElements[i].className && (inputElements[i].className.indexOf(“disableAutoComplete”) != -1)) {
      
      inputElements[i].setAttribute(“autocomplete”,”off”);
      
      }
      
      }
      
      }
      

      【讨论】:

        【解决方案10】:

        你可以试试这个:

        如果你能够使用 JavaScript 和 jQuery,你可以把它放在 html 的加载上(body onload):

        $('#theform input').val('');
        

        这个问题类似这样:Is autocomplete="off" compatible with all modern browsers?

        有些浏览器不再支持autocomplete="off"

        【讨论】:

          猜你喜欢
          • 2011-08-21
          • 2014-05-15
          • 1970-01-01
          • 2019-09-11
          • 2014-03-20
          • 2019-05-02
          • 1970-01-01
          • 1970-01-01
          • 2013-03-22
          相关资源
          最近更新 更多