Chrome自动填充/自动填充没有密码值

one*_*o12 49 html javascript google-chrome

当您为某些网站保存了用户名和密码时,Chrome会自动填充该用户名和密码,但如果您尝试获取密码输入字段的值,则为空字符串,即使有值的******.

如果单击页面上的某个位置,则无需input type="password"填写值的值.

这是fiddle 用户/传递 html和console.log命令的结构.它在这里看不到,但它可以在每个具有登录表单的页面上重现,并且用户名和密码在页面加载时自动填充.如果在单击站点上的任何其他位置之前检查字段的值,则它将为空String.

在Firefox或Internet Explorer中,情况并非如此,它将input使用密码填充元素的值.

我使用的是Windows 7旗舰版64位操作系统,谷歌Chrome版本为48.0.2564.97米

这是正常的行为,bug还是?

更新:

如果单击F5重新加载页面并检查密码字段,则密码值将在那里.如果您点击左上角Chrome中的重新加载按钮,则密码字段的值将为空字符串.

Ada*_*ton 38

这似乎是Chrome中的一个错误.当Chrome在初始页面加载时自动填写密码(但不是刷新)时,该值会显示在屏幕上的表单字段中,但passwordField.value在Javascript中查询会返回一个空字符串.如果您依赖于在Javascript中查看该值,则会阻止您这样做.一旦用户在页面上执行任何其他操作,例如单击页面上的任何位置,Javascript就会突然显示该值.

我实际上并不是100%确定这是否是一个错误,或者是否存在安全原因,例如通过欺骗浏览器填写密码来阻止隐藏框架窃取您的密码.

我们使用的解决方法是检测Chrome对其自动填充的字段所做的背景颜色更改.Chrome会将自动填充字段的背景颜色设置为黄色,即使值不是这样,此更改也始终对Javascript可见.在Javascript中检测到这一点让我们知道该字段是自动填充了一个值,即使我们在Javascript中看到该值为空白.在我们的例子中,我们有一个登录表单,其中在您填写密码字段中的某些内容之前未启用提交按钮,并且检测到值或自动填充背景颜色足以确定某些内容在字段中.然后我们可以启用提交按钮,并单击按钮(或按Enter键)立即使密码字段值对Javascript可见,因为与页面交互修复了问题,因此我们可以从那里正常进行.

  • 嗨亚当.我找到了一种方法来触发Chrome将值视为真实值,以便可以访问`.value`,并将其添加为答案.错误没有修复,但至少有一个解决方案. (3认同)

And*_*cer 23

截至2016年7月8日的工作答案

亚当正确地说这是一个错误(或预期的行为).但是,以前的答案都没有说明如何解决这个问题,所以这里有一种强制Chrome将自动完成值视为实际值的方法.

有些事情需要按顺序发生,而这只需要在Chrome而不是Firefox中运行,因此if.

首先,我们关注元素.然后我们创建一个new TextEvent和run initTextEvent,它将我们指定的自定义字符串(我用"@@@@@")添加到值的开头.这会触发Chrome真正开始表现得像真实的价值.然后我们可以删除我们添加的自定义字符串,然后我们无法聚焦.


码:

input.focus();

var event = document.createEvent('TextEvent');

if ( event.initTextEvent ) {

    event.initTextEvent('textInput', true, true, window, '@@@@@');

    input.dispatchEvent(event);

    input.value = input.value.replace('@@@@@','');

}

input.blur();
Run Code Online (Sandbox Code Playgroud)

编辑2016年8月10日

这仅适用于Windows和Android上的Chrome.不适用于OSX.此外,它将在2016年9月停止工作,根据:

https://www.chromestatus.com/features/57188​​03933560832

另外,我开了一张Chromium票.

https://bugs.chromium.org/p/chromium/issues/detail?id=636425

截至8月12日,Chrome团队的一名成员在上述票据中表示,行为不会改变,因为他们认为这不是一个错误.

长期解决方案建议:

也就是说,当前的行为已经从首次实施时进行了调整.用户不再需要与要报告的值的密码输入进行交互.用户现在只需要与页面的任何部分进行交互(发送鼠标或键盘事件).这意味着虽然在页面加载上运行验证仍然无效,但单击提交按钮将导致Chrome正确报告密码值.然后,解决方法是在提交时重新验证可能自动完成的所有输入,如果这是您尝试执行的操作.


编辑2016年12月13日:

新的Chromium门票已经打开并且收到的更好.如果有兴趣更改Chrome的此行为,请为此新票加注星标:

https://bugs.chromium.org/p/chromium/issues/detail?id=669724


Ben*_*Ben 8

继续Andy Mercer的说法,这是我的工作.像很多人一样,我不需要实际的密码值.我真的只需要知道密码框已经自动填充,这样我就可以显示正确的验证消息.

就个人而言,我不会使用建议的解决方案来检测Chrome自动填充导致的背景颜色变化.这种做法似乎很脆弱.这取决于黄色永不改变.但这可以通过扩展来改变,并在另一个基于Blink的浏览器(即Opera)中有所不同.此外,谷歌不会在将来使用不同的颜色.我的方法无论风格如何都有效.

首先,在CSS我设定的内容INPUT时,-webkit-autofil伪类适用于它:

input:-webkit-autofill {
  content: "\feff"
}
Run Code Online (Sandbox Code Playgroud)

然后,我创建了一个例程来检查要设置的内容:

const autofillContent = `"${String.fromCharCode(0xFEFF)}"`;
function checkAutofill(input) {
    if (!input.value) {
        const style = window.getComputedStyle(input);
        if (style.content !== autofillContent)
            return false;
    }

    //the autofill was detected
    input.classList.add('valid'); //replace this. do want you want to the input
    return true;
}
Run Code Online (Sandbox Code Playgroud)

最后,我调查了input以允许自动填充时间完成:

const input = document.querySelector("input[type=password]");

if (!checkAutofill(input)) {
    let interval = 0;
    const intervalId = setInterval(() => {
        if (checkAutofill(input) || interval++ >= 20)
            clearInterval(intervalId);
    }, 100);
}
Run Code Online (Sandbox Code Playgroud)

  • 我使用了类似的间隔方法,因为我发现并不总是触发单个超时,并且如果没有必要,我不想等待 2 秒。然而,我没有设置内容,而是简单地使用 document.querySelectorAll('input[type=\"password\"]:-webkit-autofill')` 检查密码字段上是否存在 webkit 自动填充元素。我每 100 毫秒检查一次,如果找到或已经过去 2 秒,我会取消该间隔。似乎是我尝试过的最强大的解决方案。 (3认同)

Ing*_*goP 8

令人惊讶的是,到 2021 年,这个问题在 Chrome 中还没有得到解决,自 2014 年以来我一直遇到自动完成问题,但仍然没有解决。

Chrome 的自动完成功能会误导用户,我不知道他们想要实现什么,但看起来不太好。

现在,表单显示向用户显示自动完成的文本(用户/电子邮件/通行证),但在后台 html 中 - 值不在元素内部。由于值不在字段中,自定义验证将禁用提交按钮。

检查字段值的脚本会说值是 null,这对用户来说更加令人困惑,因为他/她可以看到文本存在,并且可以假设它是有效的,从而导致令人困惑的删除一插入一个字符。(尴尬的是,我不得不承认我不知道你需要点击 HTML 正文,所以我想知道有多少用户不知道)

就我而言,我希望始终有空的字段,然后发现只是不必要地花费时间来使其发挥作用。

如果我们尝试,autocomplete=off我们会发现它不起作用。为了验证字段并启用按钮,我们需要做一些技巧。(请记住,我已经尝试过autocomplete=password新密码)和来自官方资源的其他类型的 Hocus-Pocus 欺骗。

最后我做到了这一点。

<script>
  $('#user').value = ' '; //one space
  $('#pass').value = ' '; // one space - if this is empty/null it will autopopulate regardless of on load event
  window.addEventListener('load', () => {
      $('#user').value = ''; // empty string
      $('#pass').value = ''; // empty string 
  });
</script>
Run Code Online (Sandbox Code Playgroud)

因此,在某些情况下,密码字段中它会闪烁一秒钟,但*并不理想:/ ...


crs*_*rsw 5

截至12月16日/ Chrome 54的另一种选择

我无法获取密码字段的值,但是在“一会儿”之后,我可以通过选择密码来获取密码的长度,这足以启用提交按钮。

setTimeout(function() {
  // get the password field
  var pwd = document.getElementById('pwd');
  pwd.focus();
  pwd.select();
  var noChars = pwd.selectionEnd;
  // move focus to username field for first-time visitors
  document.getElementById('username').focus()
  if (noChars > 0) {
    document.getElementById('loginBtn').disabled = false;
  }
}, 100);
Run Code Online (Sandbox Code Playgroud)


Sam*_*kob 5

这是我对这个问题的解决方案:

$(document).ready(function(){
  if ( $("input:-webkit-autofill").length ){
    $(".error").text("Chrome autofill detected. Please click anywhere.");
  }
});

$(document).click(function(){
  $(".error").text("");
});
Run Code Online (Sandbox Code Playgroud)

基本上,单击使输入对用户可见,因此我请用户单击,然后单击该按钮即可隐藏消息。

不是最优雅的解决方案,但可能是最快的解决方案。