如何让浏览器提示保存密码?

Eri*_*ric 135 browser ajax firefox login

嘿,我正在开发一个具有登录对话框的Web应用程序,其工作方式如下:

  1. 用户点击"登录"
  2. 登录表单HTML使用AJAX加载并显示在页面上的DIV中
  3. 用户输入用户/传递字段并单击提交.它不是<form>- 用户/通过AJAX提交
  4. 如果用户/通行证没问题,则页面会在用户登录时重新加载.
  5. 如果用户/传递不好,页面不会重新加载,但DIV中会出现错误消息,用户可以再次尝试.

这是问题所在:浏览器从不提供通常的"保存此密码?是/从不/不立即"提示它为其他网站提供的.

我尝试使用"autocomplete ='on'" 包装<div>in <form>标签,但这没有任何区别.

是否可以让浏览器提供存储密码而无需重新修改我的登录流程?

谢谢Eric

ps添加到我的问题,我肯定使用存储密码的浏览器,我从来没有点击"永远不会这个网站"...这是一个技术问题,浏览器没有检测到它是一个登录表单,而不是操作员错误:-)

Tim*_*ce7 65

我找到了这个问题的完整解决方案.(我在Chrome 27和Firefox 21中对此进行了测试).

有两件事需要知道:

  1. 触发'保存密码',然后
  2. 恢复保存的用户名/密码

1.触发'保存密码':

对于Firefox 21,当检测到包含输入文本字段的表单并且提交了输入密码字段时,将触发"保存密码".所以我们只需要使用

$('#loginButton').click(someFunctionForLogin);
$('#loginForm').submit(function(event){event.preventDefault();});
Run Code Online (Sandbox Code Playgroud)

someFunctionForLogin()ajax登录并重新加载/重定向到登录页面,同时event.preventDefault()由于提交表单而阻止原始重定向.

如果你只处理Firefox,上面的解决方案已经足够了,但它在Chrome 27中不起作用.然后你会问如何在Chrome 27中触发"保存密码".

对于Chrome 27,通过提交包含带有属性名称='用户名'的输入文本字段和带有属性名称='密码'的输入密码字段的表单,将重定向到页面触发"保存密码".因此,我们无法阻止由于提交表单而导致的重定向,但我们可以在完成ajax登录后进行重定向.(如果您希望ajax登录不重新加载页面或不重定向到页面,不幸的是,我的解决方案不起作用.)然后,我们可以使用

<form id='loginForm' action='signedIn.xxx' method='post'>
    <input type='text' name='username'>
    <input type='password' name='password'>
    <button id='loginButton' type='button'>Login</button>
</form>
<script>
    $('#loginButton').click(someFunctionForLogin);
    function someFunctionForLogin(){
        if(/*ajax login success*/) {
            $('#loginForm').submit();
        }
        else {
            //do something to show login fail(e.g. display fail messages)
        }
    }
</script>
Run Code Online (Sandbox Code Playgroud)

按下type ='button'将使单击按钮时不提交表单.然后,将函数绑定到ajax登录按钮.最后,调用$('#loginForm').submit();重定向到登录页面.如果登录页面是当前页面,则可以用当前页面替换"signedIn.xxx"以进行"刷新".

现在,您会发现Chrome 27的方法也适用于Firefox 21.因此最好使用它.

2.恢复保存的用户名/密码:

如果您已经将loginForm硬编码为HTML,那么您将发现在loginForm中恢复保存的密码没有问题.
但是,如果使用js/jquery动态生成loginForm,则保存的用户名/密码将不会绑定到loginForm,因为保存的用户名/密码仅在文档加载时绑定.
因此,您需要将loginForm硬编码为HTML并使用js/jquery动态地移动/显示/隐藏loginForm.


备注: 如果您执行ajax登录,请不要添加autocomplete='off'标签形式

<form id='loginForm' action='signedIn.xxx' autocomplete='off'>
Run Code Online (Sandbox Code Playgroud)

autocomplete='off' 将使恢复用户名/密码进入loginForm失败,因为您不允许它'自动填充'用户名/密码.

  • 在Chrome中,'event.preventDefault()'会阻止显示"保存密码"提示,请参阅此错误:https://code.google.com/p/chromium/issues/detail?id = 282488 (2认同)
  • 很多用户使用"ENTER"键提交表单,因为当用户提交表单时你已经"防止默认",没有任何事情会发生,那就是糟糕的用户体验.您可以在提交时检查输入密钥`keycode`,但是您将再次进入乞讨...... (2认同)
  • Chrome 46修复了错误的行为-不再需要任何解决方法。看到http://stackoverflow.com/a/33113374/810109 (2认同)

小智 42

使用按钮登录:

如果您使用type="button"带有onclick处理程序的登录使用ajax,则浏览器将不提供保存密码.

<form id="loginform">
 <input name="username" type="text" />
 <input name="password" type="password" />
 <input name="doLogin"  type="button" value="Login" onclick="login(this.form);" />
</form>
Run Code Online (Sandbox Code Playgroud)

由于此表单没有提交按钮且没有操作字段,因此浏览器不会提供保存密码.


使用提交按钮登录:

但是,如果您将按钮更改为type="submit"并处理提交,则浏览器将提供保存密码.

<form id="loginform" action="login.php" onSubmit="return login(this);">
 <input name="username" type="text" />
 <input name="password" type="password" />
 <input name="doLogin"  type="submit" value="Login" />
</form>
Run Code Online (Sandbox Code Playgroud)

使用此方法,浏览器应提供保存密码.


这是两种方法中使用的Javascript:

function login(f){
    var username = f.username.value;
    var password = f.password.value;

    /* Make your validation and ajax magic here. */

    return false; //or the form will post your data to login.php
}
Run Code Online (Sandbox Code Playgroud)

  • 我不明白,为什么这个答案如此赞成? (16认同)
  • 在 IE 中也适用于我。我现在可以吻你了! (2认同)

TK4*_*421 15

我一直在努力解决这个问题,最后我能够找到问题以及导致失败的原因.

这一切都源于我的登录表单被动态注入页面(使用backbone.js).只要我将登录表单直接嵌入到我的index.html文件中,一切就像魅力一样.

我认为这是因为浏览器必须知道有一个现有的登录表单,但由于我的动态注入页面,它不知道"真正的"登录表单曾经存在过.


小智 12

这个解决方案适用于我,由Eric发布在编码论坛上


它没有提示它的原因是因为浏览器需要页面以phyiscally方式刷新回服务器.您可以做的一个小技巧是使用表单执行两个操作.第一个动作是onsubmit让它调用你的Ajax代码.还有表单目标隐藏的iframe.

码:

<iframe src="ablankpage.htm" id="temp" name="temp" style="display:none"></iframe>
<form target="temp" onsubmit="yourAjaxCall();">
Run Code Online (Sandbox Code Playgroud)

看看是否会导致出现提示.

埃里克


发表于http://www.codingforums.com/showthread.php?t=123007

  • 作为一个说明,我发现如果表单是[提交给自己],Chrome 11不提供保存凭据(http://stackoverflow.com/questions/1131781/blank-html-form-action-posting-back-对个体经营).所以你需要将`action`设置为一些虚拟页面. (5认同)

Mic*_*rik 10

有一个终极解决方案强制所有浏览器(测试:chrome 25,safari 5.1,IE10,Firefox 16)要求使用jQueryajax请求保存密码:

JS:

$(document).ready(function() {
    $('form').bind('submit', $('form'), function(event) {
        var form = this;

        event.preventDefault();
        event.stopPropagation();

        if (form.submitted) {
            return;
        }

        form.submitted = true;

        $.ajax({
            url: '/login/api/jsonrpc/',
            data: {
                username: $('input[name=username]').val(),
                password: $('input[name=password]').val()
            },
            success: function(response) {
                form.submitted = false;
                form.submit(); //invoke the save password in browser
            }
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

HTML:

<form id="loginform" action="login.php" autocomplete="on">
    <label for="username">Username</label>
    <input name="username" type="text" value="" autocomplete="on" />
    <label for="password">Password</label>
    <input name="password" type="password" value="" autocomplete="on" />
   <input type="submit" name="doLogin" value="Login" />
</form>
Run Code Online (Sandbox Code Playgroud)

诀窍在于停止表单提交自己的方式(event.stopPropagation()),而是发送自己的代码($ .ajax())并在ajax的成功回调中再次提交表单,以便浏览器捕获它并显示请求密码保存.您还可以添加一些错误处理程序等.

希望它对某人有所帮助.

  • 这实际上是一个HTTP获取`login.php?username = username&password = password`,这首先取消了保存密码的全部目的 (6认同)

w00*_*00t 7

我尝试了spetson的答案,但这对我来说不适用于Chrome 18.我的工作是为iframe添加一个加载处理程序而不是中断提交(jQuery 1.7):

function getSessions() {
    $.getJSON("sessions", function (data, textStatus) {
        // Do stuff
    }).error(function () { $('#loginForm').fadeIn(); });
}
$('form', '#loginForm').submit(function (e) {
    $('#loginForm').fadeOut();
}); 
$('#loginframe').on('load', getSessions);
getSessions();
Run Code Online (Sandbox Code Playgroud)

HTML:

<div id="loginForm">
    <h3>Please log in</h3>
    <form action="/login" method="post" target="loginframe">
            <label>Username :</label>
            <input type="text" name="login" id="username" />
            <label>Password :</label>
            <input type="password" name="password" id="password"/>
            <br/>
            <button type="submit" id="loginB" name="loginB">Login!</button>
    </form>
</div>
<iframe id="loginframe" name="loginframe"></iframe>
Run Code Online (Sandbox Code Playgroud)

getSessions()执行AJAX调用,如果失败则显示loginForm div.(如果未对用户进行身份验证,则Web服务将返回403).

测试也适用于FF和IE8.


Sim*_*ckx 7

所有答案均未明确表明您可以使用 HTML5 History API 来提示保存密码。

首先,您需要确保至少有一个<form>包含密码和电子邮件或用户名字段的元素。只要您使用正确的输入类型(密码、电子邮件或用户名),大多数浏览器都会自动处理此问题。但可以肯定的是,请为每个输入元素正确设置自动完成值。

您可以在此处找到自动完成值的列表: https: //developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete

您需要的是:usernameemailcurrent-password

那么你有两种可能性:

  • 如果您在提交后导航到其他 URL,大多数浏览器将提示您保存密码。
  • 如果您不想重定向到不同的 URL,甚至不想重新加载页面(例如单页应用程序)。只需在表单的提交处理程序中阻止事件默认值(使用 e.preventDefault)即可。您可以使用 HTML5 历史记录 API 推送历史记录中的某些内容,以指示您在单页应用程序中“导航”。浏览器现在将提示保存密码和用户名。
history.pushState({}, "Your new page title");
Run Code Online (Sandbox Code Playgroud)

您还可以更改页面的 URL,但这不需要提示保存密码:

history.pushState({}, "Your new page title", "new-url");
Run Code Online (Sandbox Code Playgroud)

文档:https ://developer.mozilla.org/en-US/docs/Web/API/History/pushState

这样做的另一个好处是,如果用户输入的密码不正确,您可以防止浏览器要求保存密码。请注意,在某些浏览器中,即使您调用 .preventDefault 并且不使用历史 API,浏览器也会始终要求保存凭据。

如果您不想离开和/或修改浏览器历史记录,则可以使用replaceState(这也有效)。


bta*_*bta 6

浏览器可能无法检测到您的表单是登录表单。根据上一个问题中的一些讨论,浏览器会查找看起来像的表单字段<input type="password">。您的密码表单字段的实现与此类似吗?

编辑:为了回答下面的问题,我认为 Firefox 通过form.elements[n].type == "password"(遍历所有表单元素)来检测密码,然后通过在表单元素中向后搜索密码字段之前的文本字段来检测用户名字段(更多信息请参见此处)。据我所知,您的登录表单必须是 a 的一部分,<form>否则 Firefox 将无法检测到它。

  • 这是相似的,是的,谢谢,我会接受这个作为官方答案,因为这与我们得到的最接近。有一些令人沮丧的事情:我似乎无法(在网络上的任何地方)找到一篇简单的博客文章,上面写着“浏览器使用以下规则来检测您正在填写的表单是否是登录表单,因此他们可以提供保存用户的密码。” 考虑到这有点黑魔法(并且至少考虑到 Mozilla 是开源的),您可能会认为有人会发布启发式方法。 (3认同)

小智 6

简单的 2020 年方法

这将自动启用自动完成并在浏览器中保存密码。

  • autocomplete="on" (形式)
  • autocomplete="username" (输入,电子邮件/用户名)
  • autocomplete="current-password" (输入密码)
<form autocomplete="on">
  <input id="user-text-field" type="email" autocomplete="username"/>
  <input id="password-text-field" type="password" autocomplete="current-password"/>
</form>
Run Code Online (Sandbox Code Playgroud)

在 Apple 的文档中查看更多信息: 在 HTML 输入元素上启用密码自动填充

  • 仅供参考,这似乎需要表单提交(不能使用 XHR 和“preventDefault”),并且如果只有一个密码字段(数字安全类型应用程序),它将无法工作。与其他可能觉得有用的人分享这些发现。 (5认同)