首页 文章

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

提问于
浏览
124

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

  • 用户点击"login"

  • 登录表单HTML使用AJAX加载并显示在页面上的DIV中

  • 用户输入用户/传递字段并单击提交 . 它不是 <form> - 用户/通过AJAX提交

  • 如果用户/通行证没问题,页面会在用户登录后重新加载 .

  • 如果用户/传递不好,页面不会重新加载,但DIV中会显示错误消息,用户可以再次尝试 .

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

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

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

谢谢Eric

附:添加到我的问题,我肯定使用存储密码的浏览器,我从来没有点击“从不为这个网站”...这是一个技术问题,浏览器没有检测到它是一个登录表单,而不是运算符错误:-)

18 回答

  • 7

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

    有两件事需要知道:

    • 触发'Save password',和

    • 恢复保存的用户名/密码

    1.触发'保存密码':

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

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

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

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

    对于 Chrome 27 ,'Save password'被触发 after 它通过提交包含输入文本字段 with attribute name='username' 和输入密码字段 with attribute name='password' 的表单重定向到页面 . 因此,我们无法阻止由于提交表单而导致的重定向,但我们可以在完成ajax登录后进行重定向 . (If you want the ajax login not to reload the page or not to redirect to a page, unfortunately, my solution doesn't work.) 然后,我们可以使用

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

    类型= 'button'的按钮将使单击按钮时不提交表单 . 然后,将函数绑定到ajax登录按钮 . 最后,调用 $('#loginForm').submit(); 重定向到登录页面 . 如果登录页面是当前页面,则可以将'signedIn.xxx'替换为当前页面以生成'refresh' .

    现在,您会发现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'>
    

    autocomplete='off' 会使恢复用户名/密码进入loginForm失败,因为你不允许它'autocompletes'用户名/密码 .

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

    使用按钮登录:

    如果使用 type="button"onclick 处理程序使用 ajax 登录,则 browser won't offer 保存密码 .

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

    由于此表单 does not have a submit button 并且没有操作字段,因此浏览器不会提供保存密码 .


    使用提交按钮登录:

    但是,如果您将按钮更改为 type="submit" 并处理提交,则 browser will offer 将保存密码 .

    <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
    }
    
  • 12

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

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

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

  • -1

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


    它没有提示它的原因是因为浏览器需要页面以phyiscally方式刷新回服务器 . 您可以做的一个小技巧是使用表单执行两个操作 . 第一个动作是onsubmit让它调用你的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

  • 0

    有一个 ultimate 解决方案强制所有浏览器(测试: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
                }
            });
        });
    });
    

    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的成功回调中再次提交表单,以便浏览器捕获它并显示请求密码保存 . 您还可以添加一些错误处理程序等 .

    希望它对某人有所帮助 .

  • 11

    我尝试了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"/>
                
    <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 .

  • 0

    浏览器可能无法检测到您的表单是登录表单 . 根据this previous question中的一些讨论,浏览器会查找看起来像 <input type="password"> 的表单字段 . 您的密码表单字段是否与此类似?

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

  • -1

    以下代码已经过测试

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

    备注

    • 对于动态登录表单,需要调用 window.external.AutoCompleteSaveForm

    • Internet Explorer need a "password"-field 以显示商店密码对话框

    • Internet Explorer似乎 require a click on submit-button (即使它是假的点击)

    这是一个示例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
        });
    };
    

    备注

    如果成功,

    • "account/login"设置 cookie
      似乎需要
    • Page-redirect (由js-code启动"manually") . 我也测试了一个iframe帖子,但我没有成功 .
  • 1

    我为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":

    $('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中进行了测试 .

  • -2

    您的网站可能已经在浏览器被告知不在的列表中提示输入密码 . 在Firefox中,选项 - >安全 - >记住网站密码[复选框] - 例外[按钮]

  • 63

    在@Michal Roharik的回答中添加更多信息 .

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

    恩 .

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

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

    作为 SOLUTION 我添加了隐藏的提交输入(#loginFormHiddenSubmit)到ajax提交的表单,并且在ajax调用返回成功后,我将触发单击隐藏的提交输入 . 该页面需要刷新任何方式 . 点击可以通过以下方式触发:

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

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

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

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

  • 15

    并非每个浏览器(例如IE 6)都具有记住凭证的选项 .

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

    希望这可以暗示 . :-)

  • 1

    事实是,你可以确定浏览器有's own algorithm for guessing if you'已输入用户名/密码,例如查找 type="password" 的输入,但你无法设置强制浏览器的任何内容 .

    正如其他人所建议的那样,您可以在cookie中添加用户信息 . 如果您这样做,至少 you better encrypt it 并且不存储他们的密码 . 也许最多存储他们的用户名 .

  • 1

    您可以将对话框附加到表单,因此所有这些输入都在表单中 . 另一件事是在用户名文本字段后面输入密码文本字段 .

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

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

    你可以有一个“记住我吗?”的复选框 . 并让表单创建一个cookie来存储//用户的登录信息// info . 编辑:用户会话信息

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

相关问题