我怎样才能让浏览器提示保存密码?

嗨,我正在开发一个具有如下login对话框的Web应用程序:

  1. 用户点击“login”
  2. login表单HTML使用AJAX加载,并显示在页面上的DIV中
  3. 用户在字段中input用户名/密码并点击提交。 这不是一个<form> – 用户/通过AJAX提交
  4. 如果用户/通行证是好的,页面重新加载用户login。
  5. 如果用户/通行证不好,页面不会重新加载,但在DIV中出现错误消息,用户再次尝试。

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

我尝试用'autocomplete ='在<form> ' <form>标签中包装<div>标签,但没有任何区别。

是否有可能让浏览器提供存储密码,而不会对我的loginstream程进行重大修改?

感谢Eric

PS添加到我的问题,我肯定与存储密码的浏览器,我从来没有点击“从来没有这个网站”…这是一个技术问题,浏览器没有检测到它是一个login表单,而不是操作员错误:-)

我find了这个问题的完整解决scheme。 (我已经在Chrome 27和Firefox 21中testing过)。

有两件事要知道:

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

1.触发“保存密码”:

对于Firefox 21 ,当检测到存在包含input文本字段并提交input密码字段的表单时,会触发“保存密码”。 所以我们只需要使用

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

someFunctionForLogin()执行ajaxlogin并重新加载/redirect到login页面,而event.preventDefault()则由于提交表单而阻止原始redirect。

如果您只使用Firefox,上述解决scheme已经足够,但在Chrome 27中无法使用。然后,您将会询问如何在Chrome 27中触发“保存密码”。

对于Chrome 27 ,通过提交包含属性名为'用户名'的input文本字段和属性名为'密码'的input密码字段的表单,redirect到页面触发'保存密码' 。 因此,我们不能因为提交表单而阻止redirect,但是我们可以在完成ajaxlogin后进行redirect。 (如果您希望ajaxlogin不能重新加载页面或不重新定向页面,不幸的是,我的解决scheme不起作用。)然后,我们可以使用

 <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(eg display fail messages) } } </script> 

types=“button”的button将使表单在单击button时不被提交。 然后,将一个函数绑定到ajaxloginbutton。 最后,调用$('#loginForm').submit(); redirect到login页面。 如果login的页面是当前页面,则可以用当前页面replace“signedIn.xxx”以进行“刷新”。

现在,你会发现Chrome 27的方法也适用于Firefox 21.所以最好使用它。

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

如果您已经将loginForm硬编码为HTML,那么在loginForm中恢复已保存的密码就没有问题了。
但是,如果您使用js / jquerydynamic创buildloginForm,则保存的用户名/密码将不会绑定到loginForm,因为保存的用户名/密码仅在文档加载时才绑定。
因此,您需要将loginForm硬编码为HTML,并使用js / jquerydynamic地显示/隐藏loginForm。


备注:如果您使用ajaxlogin,请不要像标签forms那样添加autocomplete='off'

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

autocomplete='off'将使恢复用户名/密码到loginForm失败,因为你不允许它'autocompletes'的用户名/密码。

使用buttonlogin:

如果你使用type="button"和一个onclick处理程序来使用ajaxlogin,那么浏览器将不会提供保存密码。

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

由于此表单没有提交button ,也没有操作字段,所以浏览器不会提供保存密码。


使用提交buttonlogin:

但是,如果您更改button以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 } 

我自己也一直在努力,终于find了这个问题,以及是什么导致了这个问题的失败。

这一切都源于我的login表单被dynamic地注入页面(使用backbone.js)。 只要我的login表单直接embedded到我的index.html文件中,一切就像一个魅力。

我认为这是因为浏览器必须意识到存在一个现有的login表单,但是由于我正在被dynamic地注入到页面中,所以它不知道一个“真正”的login表单存在。

这个解决scheme在Eric的编码论坛上为我工作


它不提示它的原因是因为浏览器需要页面dynamic地刷新到服务器。 你可以做的一个小窍门是用表单执行两个动作。 第一个动作是onsubmit让它调用你的Ajax代码。 也有forms目标隐藏的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

有一个最终的解决scheme,强制所有浏览器(testing:铬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 } }); }); }); 

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.stopPropagation()),而不是发送自己的代码($ .ajax()),并在ajax的成功callback提交表单,使浏览器捕获并显示请求密码保存。 您也可以添加一些error handling程序等。

希望它有助于某人。

我尝试了spetson的答案,但是在Chrome 18上这对我不起作用。工作是向iframe添加一个负载处理程序,而不是中断submit(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。 (如果用户未通过validation,Web服务将返回403)。

testing过FF和IE8的工作。

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

编辑:为了回答你的问题,我想Firefox通过form.elements[n].type == "password"来检测密码(遍历所有表单元素),然后通过向后search文本字段的表单元素来检测用户form.elements[n].type == "password"段紧接在密码字段之前(更多信息在这里 )。 从我所知道的,你的login表单需要成为<form>一部分,否则Firefox将无法检测到它。

我花了很多时间阅读这个线程上的各种答案,对我来说,实际上是稍有不同的(相关的,但不同的)。 在Mobile Safari(iOS设备)上,如果页面加载时login表单为HIDDEN,则不会显示提示(显示表单并提交之后)。 您可以使用以下代码进行testing,该代码在页面加载后5秒显示表单。 删除JS和显示:无,它的作品。 我还没有find解决办法,只是张贴其他人有相同的问题,不能找出原因。

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> 

对于Prototype.JS用户,我发现了一个相当优雅的解决scheme(或者任何适合的解决scheme),是使用Prototype的最后一个坚持之一。 相应的jQuery方法的一个简单的replace应该做的伎俩。

首先,确保有一个<form>标签和一个带有类名的提交button,以后可以引用(在这种情况下是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创build一个点击观察者,它将“提交”如下所示的表单:

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

然后创buildsubmit事件的监听器,并停止它。 event.stop()将停止DOM中的所有提交事件,除非它被隐藏的inputbutton的类包装在Event.findElement (如上所示, faux-submit ):

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

这在Firefox 43和Chrome 50中testing。

您的网站可能已经在浏览器被告知不会提示保存密码的列表中。 在Firefox中,选项 – >安全 – >记住网站密码[checkbox] – exception[button]

给@Michal Roharik的答案增加一点信息。

如果你的ajax调用将返回一个返回url,你应该使用jquery在调用form.submit之前将form action属性更改为该url

恩。

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

我有类似的问题,login是用AJAX,但浏览器(Firefox,铬,Safari和IE 7-10)不会提供保存密码,如果forms(#loginForm)提交与AJAX。

作为一个解决scheme我已经添加隐藏的提交input(#loginFormHiddenSubmit)forms,由Ajax提交,并在Ajax调用将返回成功,我会触发点击隐藏提交input。 任何方式需要刷新页面。 点击可以触发:

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

我之所以添加隐藏提交button的原因是因为:

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

不会提供在IE中保存密码(虽然它已经在其他浏览器中工作)。

以下代码已经过testing

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

JS-小提琴:
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 } 

备注

  • 对于dynamiclogin表单,需要调用window.external.AutoCompleteSaveForm
  • Internet Explorer 需要一个“密码”字段来显示商店密码对话框
  • Internet Explorer似乎需要点击提交button (即使这是一个假的点击)

这是一个样例ajaxlogin代码:

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

备注

  • 如果成功,“account / login”会设置一个cookie
  • 页面redirect (由js-code“手动”启动)似乎是必需的。 我也testing了一个iframe文章,但是我没有成功。

不是每个浏览器(例如IE 6)都有选项来记住凭证。

你可以做的一件事是(一旦用户成功login)通过cookie存储用户信息,并有一个“在这台机器上记住我”选项。 这样,当用户再次出现(即使他已经注销),您的Web应用程序可以检索cookie并获取用户信息(用户ID +会话ID)并允许他/她继续工作。

希望这可以提示。 🙂

事实是,你不能强迫浏览器问。 我确定浏览器有它自己的algorithm来猜测你是否input了用户名/密码,比如查找type="password"的input,但是你不能设置任何东西来强制浏览器。

像其他人所build议的那样,您可以在cookie中添加用户信息。 如果你这样做, 你最好encryption它 ,至less不要存储他们的密码。 也许最多存储他们的用户名。

您可以将对话框附加到表单中,所有这些input都以表单forms存在。 另一件事是密码文本字段紧跟在用户名文本字段之后。

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

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

使用cookie可能是最好的方法来做到这一点。

你可以有一个checkbox“记住我?” 并有forms创build一个cookie来存储//用户的login信息。 编辑:用户会话信息

要创build一个cookie,您需要使用PHP处理login表单。