Как я могу получить браузер с просьбой сохранить пароль? - PullRequest
127 голосов
/ 04 марта 2010

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

  1. Пользователь нажимает кнопку «войти»
  2. Форма входа HTML загружается с AJAXи отображается в DIV на странице
  3. Пользователь вводит пользователя / передает в поля и нажимает кнопку отправки.Это НЕ <form> - пользователь / пароль передается через AJAX
  4. Если с пользователем / паролем все в порядке, страница перезагружается, когда пользователь вошел в систему.
  5. Если пользователь / пароль плохой, страница делаетНЕ перезагружается, но в DIV появляется сообщение об ошибке, и пользователь пытается повторить попытку.

Вот проблема: браузер никогда не предлагает обычную подсказку «Сохранить этот пароль? Да / Никогда / Не сейчас», что он делаетдля других сайтов.

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

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

спасибо, Эрик

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

Ответы [ 18 ]

64 голосов
/ 16 июня 2013

Я нашел полное решение для этого вопроса. (Я проверял это в 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.

Для Chrome 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>

Кнопка с type = 'button' сделает форму не подлежащей отправке при нажатии кнопки. Затем, связывание функции с кнопкой для входа в AJAX. Наконец, вызов $('#loginForm').submit(); перенаправляет на страницу входа. Если страница входа в систему является текущей страницей, то вы можете заменить «SignIn.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, поскольку вы не разрешаете ему «автозаполнение» имени пользователя / пароля.

38 голосов
/ 13 ноября 2011

Использование кнопки для входа в систему:

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

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


Использование кнопки submit для входа в систему:

Однако, если вы измените кнопку на 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
}
15 голосов
/ 08 июня 2012

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

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

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

12 голосов
/ 25 января 2011

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


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

11 голосов
/ 28 марта 2013

Существует окончательное решение, позволяющее всем браузерам (протестировано: 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 отправьте форму снова, чтобы браузер перехватил ее и отобразить запрос на сохранение пароля. Вы также можете добавить обработчик ошибок и т. Д.

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

7 голосов
/ 02 февраля 2012

Я попробовал ответ спецона , но это не сработало для меня в 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-вызов и показывает div loginForm в случае сбоя. (Веб-служба вернет 403, если пользователь не аутентифицирован).

Проверено на работу в FF и IE8.

4 голосов
/ 04 марта 2010

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

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

1 голос
/ 28 мая 2016

Я нашел довольно элегантное решение (или взломать, что угодно) для пользователей 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.

1 голос
/ 13 ноября 2012

Я потратил много времени, читая различные ответы в этой теме, и для меня это было что-то немного другое (связанное, но другое). В Mobile 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>
1 голос
/ 16 января 2015

Следующий код проверен на

  • Хром 39.0.2171.99м: РАБОТАЕТ
  • 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-Fiddle:
http://jsfiddle.net/ocozggqu/

Post-код:

// modified post-code from /100741/javascript-post-zapros-kak-forma-otpravit
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
    });
};

Примечания

  • "account / login" устанавливает cookie в случае успеха
  • Перенаправление страницы («вручную» инициируется js-кодом), по-видимому, требуется. Я также проверил пост iframe, но мне это не удалось.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...