Как я могу заставить браузер запрашивать сохранение пароля?

Эй, я работаю над веб-приложением, которое имеет диалог входа в систему, который работает следующим образом:

  1. пользователь нажимает кнопку "Войти"
  2. форма входа HTML загружается с AJAX и отображается в DIV на странице
  3. пользователь вводит user / pass в поля и нажимает submit. Это не <form> -- user / pass отправляются через AJAX
  4. если пользователь / pass в порядке, страница перезагружается с пользователем, вошедшим в систему.
  5. если пользователь / pass плохи, страница не перезагружается, но появляется сообщение об ошибке в DIV и пользователь могут попробовать еще раз.

вот проблема: браузер не предлагает обычный "сохранить этот пароль? Да / никогда / не сейчас " подскажите, что он делает для других сайтов.

Я попытался обернуть <div> на <form> теги с "autocomplete= 'on'", но это не имело никакого значения.

можно ли сделать браузер предложить сохранить пароль без серьезной переделки мой логин?

спасибо Эрик!--4-->

p.s. добавить к моему вопрос, я определенно работаю с браузерами, которые хранят пароли, и я никогда не нажимал "никогда для этого сайта" ...это техническая проблема с браузером, не обнаруживая, что это форма входа, а не ошибка оператора :-)

18 ответов


я нашел полное решение этого вопроса. (Я испытал это в Chrome 27 и Firefox 21).

есть две вещи, чтобы знать:

  1. триггер 'сохранить пароль', и
  2. восстановить сохраненное имя пользователя / пароль

1. Триггер "сохранить пароль":

на Firefox 21, "сохранить пароль" запускается, когда он обнаруживает, что есть форма, содержащая входной текст поле и поле ввода пароля отправляются. Поэтому нам просто нужно использовать

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

someFunctionForLogin() делает логин ajax и перезагружает / перенаправляет на страницу входа в то время как event.preventDefault() блокирует исходное перенаправление из-за отправки формы.

если вы имеете дело только с Firefox, вышеупомянутого решения достаточно, но оно не работает в Chrome 27. Затем вы спросите, как вызвать "сохранить пароль" в Chrome 27.

на хром 27 сохранить пароль срабатывает после он перенаправляется на страницу, отправив форму, содержащую текстовое поле ввода С атрибутом name= 'username' и поле ввода пароля С атрибутом name='password'. Поэтому мы не можем заблокировать перенаправление из-за отправки формы, но мы можем сделать перенаправление после того, как мы сделали вход 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>

кнопка с типом= 'button' сделает форму, которая не будет отправлена при нажатии кнопки. Затем привязка функции к кнопке для входа ajax. Наконец, зову $('#loginForm').submit(); перенаправляет на страницу входа. Если страница входа является текущей страницей, вы можете заменить 'signedIn.xxx 'по текущей странице, чтобы сделать "обновить".

теперь вы обнаружите, что метод для Chrome 27 также работает в Firefox 21. Так это лучше использовать его.

2. Восстановить сохраненное имя пользователя / пароль:

если у вас уже есть LoginForm жестко закодированный как HTML, то вы не найдете никаких проблем для восстановления сохраненного пароля в loginForm.
Однако сохраненное имя пользователя / пароль не будет привязываться к loginForm, если вы используете JS/jquery для динамического создания loginForm, потому что сохраненное имя пользователя / пароль привязывается только при загрузке документа.
Поэтому нужно жестко в LoginForm, который будет в HTML и использовать JS/jQuery для перемещения/показать/динамически скрывать LoginForm, который будет.


замечание: Если вы делаете логин ajax, не добавляйте autocomplete='off' в форме тег

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

autocomplete='off' сделает восстановление имени пользователя / пароля в loginForm не удается, потому что вы не позволяете ему "автозаполняет" имя пользователя/пароль.


С помощью логин:

если вы используете 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
}

Я сам боролся с этим, и я, наконец, смог отследить проблему и то, что заставляло ее терпеть неудачу.

все это произошло из - за того, что моя форма входа в систему динамически вводилась на страницу (используя backbone.в JS). Как только я встраиваю свою форму входа непосредственно в свой индекс.HTML-файл, все работало как шарм.

Я думаю, это потому, что браузер должен знать, что существует существующая форма входа в систему, но так как мой динамически вводимый на страницу, он не знал, что "реальная" форма входа когда-либо существовала.


Это решение сработало для меня, опубликованное Эриком на codingforums


причина, по которой он не запрашивает его, заключается в том, что браузеру нужна страница для 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


здесь конечная решение, чтобы заставить все браузеры (проверено: 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>

трюк заключается в остановке формы, чтобы представить свой собственный путь (событие.stopPropagation ()), вместо этого отправьте свой собственный код ($.ajax ()) и в обратном вызове успеха ajax снова отправьте форму, чтобы браузер ловит его и отображает запрос на сохранение пароля. Вы также можете добавить обработчик ошибок и т. д.

надеюсь, что это помогло кому-то.


пробовал 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();

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, если он терпит неудачу. (Веб-служба вернет 403, если пользователь не прошел проверку подлинности).

протестировано для работы в FF и IE8.


браузер может не обнаружить, что ваша форма является формой входа в систему. Согласно некоторым из обсуждений в этот предыдущий вопрос, браузер ищет поля формы, которые выглядят как <input type="password">. Ваше поле формы пароля реализовано аналогично этому?

Edit: чтобы ответить на ваши вопросы ниже, я думаю, что Firefox обнаруживает пароли к form.elements[n].type == "password" (итерация по всем элементам формы), а затем обнаруживает поле username путем поиска назад через элементы формы для текстового поля непосредственно перед полем пароля (подробнее здесь). Из того, что я могу сказать, ваша форма входа в систему должна быть частью <form> или Firefox не обнаружит его.


Я потратил много времени, читая различные ответы на эту тему, и для меня это было на самом деле что-то немного другое (связанное, но другое). На мобильных устройствах Safari (iOS), если форма входа скрыта при загрузке страницы, приглашение не появится (после того, как вы покажете форму, затем отправьте ее). Вы можете проверить следующий код, который отображает форму 5 секунд после загрузки страницы. Удалите JS и дисплей: нет, и он работает. Я еще предстоит найти решение этой проблемы, просто выложил на случай, если кто-то еще имеет ту же проблему и не может выяснить причину.

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 39.0.2171.99 m: рабочий
  • Android Chrome 39.0.2171.93: работа
  • Android stock-браузер (Android 4.4): не работает
  • Internet Explorer 5+ (эмулируется): работа
  • Internet Explorer 11.0.9600.17498 / обновление-версия: 11.0.15: рабочий
  • Firefox 35.0: Работа

JS-Скрипка:
http://jsfiddle.net/ocozggqu/

Post-code:

// 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 нужен "пароль"-поле для отображения диалога магазин-пароль -
  • 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
    });
};

Примечания

  • "учетная запись/логин" устанавливает cookie в случае успеха
  • страница-перенаправление ("вручную", инициированный JS-кодом), кажется, требуется. Я также протестировал iframe-post, но мне это не удалось.

Я нашел довольно элегантное решение (или взломать, что угодно) для прототипа.Пользователи JS, будучи одним из последних несогласных с использованием прототипа. Простая замена соответствующих методов 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.


ваш сайт, вероятно, уже находится в списке, где браузеру сказано не запрашивать сохранение пароля. В firefox параметры - > безопасность - > запомнить пароль для сайтов[флажок] - исключения[кнопка]


добавьте немного больше информации в ответ @Michal Roharik.

если ваш вызов ajax вернет url-адрес возврата, вы должны использовать jquery для изменения атрибута действия формы на этот url-адрес перед вызовом формы.submit

ex.

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

у меня была аналогичная проблема, вход был сделан с ajax, но браузеры (firefox, chrome, safari и IE 7-10) не предложили бы сохранить пароль, если форма (#loginForm) отправлена с ajax.

Как решение я добавил скрытый ввод отправки (#loginFormHiddenSubmit) в форму, которая была отправлена ajax, и после того, как вызов ajax вернет успех, я вызову щелчок для скрытого ввода отправки. Страница в любом случае необходимо обновить. Щелчок может быть вызван с:

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

причина, по которой я добавил скрытую кнопку отправки, заключается в том, что:

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

не предложил бы сохранить пароль в IE (хотя он работал в других браузерах).


Не каждый браузер (например, IE 6) имеет опции для запоминания учетных данных.

одна вещь, которую вы можете сделать ,это (как только пользователь успешно войдет в систему) хранить информацию о пользователе через cookie и иметь опцию "Запомнить меня на этой машине". Таким образом, когда пользователь приходит снова (даже если он вышел из системы), ваше веб-приложение может получить файл cookie и получить информацию о пользователе (идентификатор пользователя + идентификатор сеанса) и позволить ему/ей продолжать работать.

надеюсь, это может быть наводящим на размышления. :-)


правда в том, что вы не можете заставить браузер спрашивать. Я уверен, что браузер имеет свой собственный алгоритм угадывания, если вы ввели имя пользователя / пароль, например, ищете ввод type="password" но вы не можете установить ничего, чтобы заставить браузер.

вы можете, как предлагают другие, добавить информацию о пользователе в файл cookie. Если вы сделаете это, вы лучше зашифровать его по крайней мере и не храните свой пароль. Возможно, сохраните их имя пользователя не более.


вы можете прикрепить диалоговое окно к форме, поэтому все эти входы находятся в форме. Другое дело, сделать текстовое поле пароля сразу после текстового поля имени пользователя.


это работает намного лучше для меня, потому что это 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>

использование cookie, вероятно, будет лучшим способом сделать это.

У вас может быть флажок " помните меня? и имеют форму создать файл cookie для хранения //пользователя// инфо. EDIT: информация о сеансе пользователя

чтобы создать файл cookie, вам нужно обработать форму входа в систему с помощью PHP.