嘿,我正在开发一个网络应用程序,它有一个像这样工作的登录对话框:
<form>
- 用户/通过AJAX提交问题在于:浏览器从不提供通常的“保存此密码?是/从不/不现在”提示它为其他网站提供的。
我尝试将<div>
标记在<form>
标记中,并使用“autocomplete ='on'”,但这没有任何区别。
是否可以让浏览器提供存储密码而无需重新修改我的登录流程?
感谢 埃里克
P.S。添加到我的问题,我肯定使用存储密码的浏览器,我从来没有点击“从不为这个网站”...这是一个技术问题,浏览器没有检测到它是一个登录表单,而不是运算符错误: - )
答案 0 :(得分:64)
我找到了这个问题的完整解决方案。 (我已经在Chrome 27和Firefox 21中对此进行了测试。)
有两件事要知道:
对于 Firefox 21 ,当检测到包含输入文本字段且提交输入密码字段的表单时,会触发“保存密码”。所以我们只需要使用
$('#loginButton').click(someFunctionForLogin);
$('#loginForm').submit(function(event){event.preventDefault();});
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>
按下type ='button'将使单击按钮时不提交表单。
然后,将函数绑定到ajax登录按钮。最后,调用$('#loginForm').submit();
重定向到登录页面。如果登录页面是当前页面,那么您可以用当前页面替换“signedIn.xxx”以进行“刷新”。
现在,您会发现Chrome 27的方法也适用于Firefox 21.所以最好使用它。
如果您已经将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'
会使登录帐户恢复用户名/密码失败,因为您不允许它“自动填充”用户名/密码。
答案 1 :(得分:37)
如果您使用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>
由于此表单 没有提交按钮 且没有操作字段,因此浏览器不会提供保存密码。
但是,如果您将按钮更改为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
}
答案 2 :(得分:15)
我一直在努力解决这个问题,最后我能够找到问题以及导致问题失败的原因。
这一切都源于我的登录表单被动态注入页面(使用backbone.js)。只要我将登录表单直接嵌入到我的index.html文件中,一切就像魅力一样。
我认为这是因为浏览器必须知道有一个现有的登录表单,但由于我的动态注入页面,它不知道“真正的”登录表单曾经存在。
答案 3 :(得分:12)
此解决方案适用于我,由Eric发布在编码论坛上
它没有提示它的原因是因为浏览器需要页面以phyiscally方式刷新回服务器。您可以做的一个小技巧是使用表单执行两个操作。第一个动作是onsubmit让它调用你的Ajax代码。同时让表单定位一个隐藏的iframe。
代码:
<iframe src="ablankpage.htm" id="temp" name="temp" style="display:none"></iframe>
<form target="temp" onsubmit="yourAjaxCall();">
看看是否会导致出现提示。
埃里克
答案 4 :(得分:11)
有一个终极解决方案强制所有浏览器(已测试:chrome 25,safari 5.1,IE10,Firefox 16)要求使用 jQuery 和 ajax 请求:
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的成功回调中再次提交表单,以便浏览器捕获它并显示密码保存请求。 您还可以添加一些错误处理程序等。
希望对某人有所帮助。
答案 5 :(得分:7)
我尝试了spetson's answer,但这对我来说不适用于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();
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。
答案 6 :(得分:4)
浏览器可能无法检测到您的表单是登录表单。根据{{3}}中的一些讨论,浏览器会查找看起来像<input type="password">
的表单字段。您的密码表单字段是否与此类似?
编辑:为了回答下面的问题,我认为Firefox会通过form.elements[n].type == "password"
检测密码(遍历所有表单元素),然后通过向后搜索表单元素来检测用户名字段密码字段前面的文本字段(更多信息this previous question)。据我所知,您的登录表单需要成为<form>
的一部分,否则Firefox将无法检测到它。
答案 7 :(得分:3)
这将自动启用自动完成功能并在浏览器中保存密码。
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>
在Apple文档中查看更多信息: Enabling Password AutoFill on an HTML Input Element
答案 8 :(得分:2)
没有一个答案已经很清楚了,您可以使用HTML5历史记录API提示保存密码。
首先,您需要确保至少有一个<form>
元素,其中包含密码,电子邮件或用户名字段。只要您使用正确的输入类型(密码,电子邮件或用户名),大多数浏览器都会自动处理此问题。但是请确保为每个输入元素正确设置自动完成值。
您可以在此处找到自动完成值的列表:https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete
您需要的是:username
,email
和current-password
那么您有两种可能性:
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
这还有一个好处,即如果用户输入的密码不正确,您可以防止浏览器要求保存密码。请注意,在某些浏览器中,即使您调用.preventDefault并且不使用历史记录API,浏览器也会始终要求保存凭据。
如果您不想导航和/或修改浏览器历史记录,可以改用replaceState(这也可以)。
答案 9 :(得分:1)
我花了很多时间在这个帖子上阅读各种答案,而对我来说,实际上它有些不同(相关但不同)。在Mobile Safari(iOS设备)上,如果页面加载时登录表单为HIDDEN,则不会出现提示(显示表单后再提交)。您可以使用以下代码进行测试,该代码在页面加载后5秒显示表单。删除JS和display:none,它可以工作。我还没有找到解决方案,只是发布以防其他人有同样的问题而无法找出原因。
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>
答案 10 :(得分:1)
以下代码在
上进行了测试 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
}
备注
window.external.AutoCompleteSaveForm
以下是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
});
};
说明
答案 11 :(得分:1)
我为Prototype.JS用户找到了一个相当优雅的解决方案(或者黑客,无论多么合适),是使用Prototype的最后一个坚持者之一。简单地替换相应的jQuery方法应该可以解决问题。
首先,确保有一个sa <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
创建一个点击观察者,它将提交&#34;提交&#34;形式如图所示:
$('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中进行了测试。
答案 12 :(得分:0)
向@Michal Roharik的回答添加更多信息。
如果你的ajax调用将返回一个返回url,你应该使用jquery在调用form.submit之前将表单action属性更改为该url
离。
$(form).attr('action', ReturnPath);
form.submitted = false;
form.submit();
答案 13 :(得分:0)
我有类似的问题,登录是用ajax完成的,但是如果使用ajax提交表单(#loginForm),浏览器(firefox,chrome,safari和IE 7-10)将无法保存密码。
作为一个解决方案我添加了隐藏的提交输入(#loginFormHiddenSubmit)到ajax提交的表单,并且在ajax调用返回成功之后我会触发一个点击隐藏的提交输入。该页面需要刷新任何方式。点击可以通过以下方式触发:
jQuery('#loginFormHiddenSubmit').click();
我添加隐藏提交按钮的原因是:
jQuery('#loginForm').submit();
不会在IE中保存密码(虽然它在其他浏览器中有效)。
答案 14 :(得分:0)
您的网站可能已经在浏览器被告知不提示保存密码的列表中。在Firefox中,选项 - &gt;安全 - &gt;记住网站密码[复选框] - 例外[按钮]
答案 15 :(得分:-1)
您可以将对话框附加到表单,因此所有这些输入都在表单中。另一件事是在用户名文本字段后面输入密码文本字段。
答案 16 :(得分:-1)
事实是,你不能强迫浏览器询问。我确定浏览器有自己的算法来猜测你是否输入了用户名/密码,例如查找type="password"
的输入,但你无法设置强制浏览器的任何内容。
您可以像其他人建议的那样在Cookie中添加用户信息。如果您这样做,最好加密至少并且不要存储他们的密码。也许最多存储他们的用户名。
答案 17 :(得分:-1)
这项工作对我来说更好,因为它是100%ajaxed并且浏览器检测到登录。
<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>
答案 18 :(得分:-1)
并非每个浏览器(例如IE 6)都有记住凭据的选项。
您可以做的一件事是(一旦用户成功登录)通过cookie存储用户信息并拥有“在此机器上记住我”选项。这样,当用户再次来访时(即使他已经注销),您的Web应用程序可以检索cookie并获取用户信息(用户ID +会话ID)并允许他/她继续工作。
希望这可能具有启发性。 : - )
答案 19 :(得分:-2)
使用cookie可能是最好的方法。
你可以勾选“记住我吗?”并让表单创建一个cookie来存储//用户的登录信息// info。 编辑:用户会话信息
要创建cookie,您需要使用PHP处理登录表单。