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

嘿,我正在开发一个网络应用程序,它的登录对话框是这样工作的:

  1. 用户点击“登录”
  2. 登录表单 HTML 加载了 AJAX 并以 DIV 显示在页面上
  3. 用户在字段中输入 User/pass 并点击提交。它不是 <form>—— User/pass 是通过 AJAX 提交的
  4. 如果 user/pass 没有问题,则用户登录后重新加载页面。
  5. 如果用户/通过是坏的,页面不重新加载,但错误消息出现在 DIV 和用户获得再次尝试。

问题是: 浏览器从来不会提供“保存此密码?”?“是/从不/不是现在”提示,它为其他网站做。

我尝试用“ autocomplete = ‘ on’”在 <form>标记中包装 <div>,但是没有什么区别。

有没有可能让浏览器提供存储密码,而不需要对我的登录流程进行重大修改?

谢谢 艾瑞克

另外,我的问题是,我绝对是和存储密码的浏览器一起工作的,而且我从来没有点击“永远不会为这个网站”... 这是一个技术问题,因为浏览器没有检测到它是一个登录表单,而不是操作员错误: -)

168655 次浏览

您的站点可能已经在告诉浏览器不要提示保存密码的列表中。在火狐中,选项-> 安全-> 记住站点的密码[复选框]-异常[按钮]

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

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

不是每个浏览器(例如 IE6)都有记忆凭据的选项。

您可以做的一件事是(一旦用户成功登录)通过 cookie 存储用户信息,并有一个“ RememberMe on this machine”选项。这样,当用户再次访问时(即使他已经退出) ,Web 应用程序可以检索 cookie 并获取用户信息(用户 ID + 会话 ID) ,并允许他/她继续工作。

希望这能有点启发性。 : -)

使用 cookie 可能是最好的方法。

你可以在“记得我吗?并让表单创建一个 cookie 来存储//用户的登录//信息。 编辑: 用户会话信息

要创建 cookie,需要使用 PHP 处理登录表单。

事实上,你不能强迫浏览器去问。我确信浏览器有自己的算法来猜测你是否输入了用户名/密码,比如寻找 type="password"的输入,但是你不能设置任何东西来强制浏览器。

正如其他人建议的那样,您可以在 cookie 中添加用户信息。如果你这样做,你最好把它加密至少不存储自己的密码。也许最多存储他们的用户名。

这个解决方案对我很有效,Eric 在编码论坛上发布了这个解决方案


之所以没有提示,是因为浏览器需要页面物理刷新回服务器。您可以使用表单执行两个操作。第一个动作是 oncommit 让它调用您的 Ajax 代码。也有一个隐藏的 iframe 窗体目标。

密码:

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

看看这是否会导致出现提示符。

艾瑞克


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

使用 纽扣登入:

如果使用带有 onclick处理程序的 type="button"使用 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>

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


使用 服从按钮登录:

但是,如果您更改按钮为 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>

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


下面是两种方法中使用的 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
}

您可以将对话框附加到窗体,这样所有的输入都在一个窗体中。另一种方法是在用户名文本字段之后设置密码文本字段。

我试过 斯佩特森的回答,但是在 Chrome18上不管用。真正起作用的是向 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();

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>

GetSessions ()执行 AJAX 调用并在失败时显示 loginForm div。(如果用户未经身份验证,Web 服务将返回403)。

测试工作在 FF 和 IE8以及。

我自己也一直在努力解决这个问题,最后我终于找到了问题所在,以及导致它失败的原因。

这一切都源于我的登录表单被动态地注入到页面中(使用 backbone.js)。只要我将登录表单直接嵌入到 index.html 文件中,一切都会像魔法一样运转起来。

我认为这是因为浏览器必须知道有一个已经存在的登录表单,但是由于我的登录表单被动态地注入到页面中,它不知道“真正的”登录表单曾经存在过。

我花了很多时间阅读这个帖子上的各种答案,对我来说,它实际上是有点不同(相关,但不同)。在 Mobile Safari (iOS 设备)上,如果页面加载时登录表单是隐藏的,则不会出现提示(在显示表单后提交)。您可以使用以下代码进行测试,该代码在页面加载后5秒显示窗体。删除 JS 和显示: 无,它工作。我还没有找到一个解决这个问题的办法,只是张贴在万一其他人有同样的问题,不能找出原因。

约翰逊:

$(function() {
setTimeout(function() {
$('form').fadeIn();
}, 5000);
});

HTML:

<form method="POST" style="display: none;">
<input name='email' id='email' type='email' placeholder='email' />
<input name='password' id='password' type='password' placeholder='password' />
<button type="submit">LOGIN</button>
</form>

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

约翰逊:

$(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
}
});
});
});

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>

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

希望对谁有帮助。

给@Michal Roharik 的回答添加更多信息。

如果您的 ajax 调用将返回一个 url,那么您应该使用 jquery 将 form action 属性更改为该 url,然后再调用 form.mit

前男友。

$(form).attr('action', ReturnPath);
form.submitted = false;
form.submit();

我为这个问题找到了一个完整的解决方案(我已经在 Chrome27和 Firefox21中测试过)。

有两件事要知道:

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

1. 触发“保存密码”:

对于 火狐21,当检测到有一个包含输入文本字段和输入密码字段的表单被提交时,将触发“保存密码”。所以我们只需要

$('#loginButton').click(someFunctionForLogin);
$('#loginForm').submit(function(event){event.preventDefault();});

someFunctionForLogin()执行 ajax 登录并重新加载/重定向到已签名的页面,而 event.preventDefault()由于提交表单而阻止原来的重定向。

如果你只使用火狐浏览器,上面的解决方案就足够了,但是在 Chrome27中不能使用。然后你会问如何在 Chrome27中触发“保存密码”。

对于 < em > 铬27 ,‘ Save password’被触发 之后,它通过提交包含输入文本字段 使用属性 name = ‘ username’和输入密码字段 使用属性 name = ‘ password’的表单被重定向到页面。因此,我们不能因为提交表单而阻止重定向,但是我们可以在完成 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>

当按钮被单击时,type = ‘ Button’将使表单不被提交。 然后,为 ajax 登录将一个函数绑定到按钮。最后,调用 $('#loginForm').submit();会重定向到登录页面。如果登录页面是当前页面,那么您可以将‘ signedIn.xxx’替换为当前页面以进行‘刷新’。

现在,你会发现 Chrome27的方法也可以在 Firefox21中使用。所以最好还是用它。

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

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


备注: 如果使用 ajax 登录,请不要添加标记形式的 autocomplete='off',如

<form id='loginForm' action='signedIn.xxx' autocomplete='off'>

autocomplete='off'将使恢复到 loginForm 的用户名/密码失败,因为您不允许它“自动完成”用户名/密码。

我有类似的问题,登录是用 ajax 完成的,但浏览器(Firefox,chrome,safari 和 IE 7-10)不会提供保存密码,如果表单(# loginForm)是用 ajax 提交的。

作为一个 解决方案,我已经添加了隐藏提交输入(# loginFormHiddenSubmit)到由 ajax 提交的表单中,在 ajax 调用返回成功后,我会触发一个点击来隐藏提交输入。以任何方式刷新页面。点击可以通过以下方式触发:

jQuery('#loginFormHiddenSubmit').click();

我添加隐藏提交按钮的原因是:

jQuery('#loginForm').submit();

不会提供在 IE 中保存密码(尽管它在其他浏览器中可以工作)。

这对我来说更好,因为它是100% Ajax 和浏览器检测登录。

<form id="loginform" action="javascript:login(this);" >
<label for="username">Username</label>
<input name="username" type="text" value="" required="required" />
<label for="password">Password</label>
<input name="password" type="password" value="" required="required" />
<a href="#" onclick="document.getElementById("loginform").submit();"  >Login</a>
</form>

测试下面的代码

  • Chrome 39.0.2171.99 m: WORKING Chrome 39.0.2171.99 m: 工作
  • Android Chrome 39.0.2171.93: WORKING Android Chrome 39.0.2171.93: 运行
  • Android 股票浏览器(Android 4.4) : 不工作
  • Internet Explorer 5 + (模拟) : 工作
  • Internet Explorer 11.0.9600.17498/更新-版本: 11.0.15: 工作
  • 火狐35.0: 工作

JS-Fiddle:
Http://jsfiddle.net/ocozggqu/

邮编:

// modified post-code from https://stackoverflow.com/questions/133925/javascript-post-request-like-a-form-submit
function post(path, params, method)
{
method = method || "post"; // Set method to post by default if not specified.


// The rest of this code assumes you are not using a library.
// It can be made less wordy if you use one.


var form = document.createElement("form");
form.id = "dynamicform" + Math.random();
form.setAttribute("method", method);
form.setAttribute("action", path);
form.setAttribute("style", "display: none");
// Internet Explorer needs this
form.setAttribute("onsubmit", "window.external.AutoCompleteSaveForm(document.getElementById('" + form.id + "'))");


for (var key in params)
{
if (params.hasOwnProperty(key))
{
var hiddenField = document.createElement("input");
// Internet Explorer needs a "password"-field to show the store-password-dialog
hiddenField.setAttribute("type", key == "password" ? "password" : "text");
hiddenField.setAttribute("name", key);
hiddenField.setAttribute("value", params[key]);


form.appendChild(hiddenField);
}
}


var submitButton = document.createElement("input");
submitButton.setAttribute("type", "submit");


form.appendChild(submitButton);


document.body.appendChild(form);


//form.submit(); does not work on Internet Explorer
submitButton.click(); // "click" on submit-button needed for Internet Explorer
}

备注

  • 对于动态登录表单,需要调用 window.external.AutoCompleteSaveForm
  • Internet Explorer 需要一个“ password”字段显示存储密码对话框
  • Internet Explorer 似乎是 需要点击提交按钮(即使是假点击)

下面是一个 Ajax 登录代码示例:

function login(username, password, remember, redirectUrl)
{
// "account/login" sets a cookie if successful
return $.postJSON("account/login", {
username: username,
password: password,
remember: remember,
returnUrl: redirectUrl
})
.done(function ()
{
// login succeeded, issue a manual page-redirect to show the store-password-dialog
post(
redirectUrl,
{
username: username,
password: password,
remember: remember,
returnUrl: redirectUrl
},
"post");
})
.fail(function ()
{
// show error
});
};

备注

  • 如果成功,“帐户/登录”将设置 饼干
  • 似乎需要 Page-redirect (由 js-code“手动”启动)。我还测试了一个 iframe-post,但是没有成功。

我为 Prototype.JS 用户找到了一个相当优雅的解决方案(或者黑客技术,随便什么都行) ,它是使用 Prototype 的最后一批坚持者之一。简单地替换相应的 jQuery 方法就可以解决这个问题。

首先,确保有一个 <form>标记,以及一个带有类名的提交按钮,类名可以在以后引用(在本例中为 faux-submit) ,该按钮嵌套在一个样式设置为 display:none的元素中,如下所示:

<form id="login_form" action="somewhere.php" method="post">
<input type="text" name="login" />
<input type="password" name="password" />
<div style="display:none">
<input class="faux-submit" type="submit" value="Submit" />
</div>
<button id="submit_button">Login</button>
</form>

然后为 button创建一个点击观察器,它将“提交”表单,如图所示:

$('submit_button').observe('click', function(event) {
$('login_form').submit();
});

然后为 submit事件创建一个侦听器,并停止它。event.stop()将停止 DOM 中的所有提交事件,除非它被包装在 Event.findElement中,带有隐藏输入按钮的类(如上所述,faux-submit) :

document.observe('submit', function(event) {
if (event.findElement(".faux-submit")) {
event.stop();
}
});

这是在 Firefox 43和 Chrome 50中进行的测试。

简单的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>

查看更多苹果的文档: 在 HTML 输入元素上启用密码自动填充

没有一个答案已经清楚地表明您可以使用 HTML5历史 API 来提示保存密码。

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

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

你需要的是: usernameemailcurrent-password

那么你有两种可能:

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

您也可以更改网页的 URL,但不需要这样做来提示保存密码:

history.pushState({}, "Your new page title", "new-url");

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

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

如果不想导航或修改浏览器历史记录,可以使用 replaceState (这也可以)。

我尝试了所有的方法。没有什么是完全有效的。这就是我的解决办法。对我有用。我希望这对你有用。 我将电子邮件/用户名输入替换为一个文本区域

<form>
<textarea required placeholder="Email" rows=1></textarea>
<input required placeholder="Password" type="password" readonly onfocus="this.removeAttribute('readonly')" />
<button>
Sign in
</button>