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

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

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

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

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

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

спасибо Эрик

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

22 ответа

Решение

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

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

Если вы используете 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). Как только я вставил свою форму входа непосредственно в мой файл index.html, все заработало как чудо.

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

Простой подход 2020

Это автоматически включит автозаполнение и сохранит пароль в браузерах.

  • 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: Включение автозаполнения пароля для элемента ввода HTML

Это решение работало для меня, размещенного Эриком на codingforums


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

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

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

Я попробовал ответ спецона, но это не сработало для меня в 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.

Ни один из ответов уже не дает понять, что вы можете использовать API истории HTML5, чтобы предложить сохранить пароль.

Во-первых, вам нужно убедиться, что у вас есть хотя бы <form>элемент с паролем и адресом электронной почты или полем имени пользователя. Большинство браузеров обрабатывают это автоматически, если вы используете правильные типы ввода (пароль, адрес электронной почты или имя пользователя). Но, чтобы быть уверенным, правильно установите значения автозаполнения для каждого элемента ввода.

Вы можете найти список значений автозаполнения здесь: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete

Вам понадобятся: username, email а также current-password

Тогда у вас есть две возможности:

  • Если после отправки вы перейдете к другому URL-адресу, большинство браузеров предложит сохранить пароль.
  • Если вы не хотите перенаправлять на другой URL-адрес или даже перезагружать страницу (например, одностраничное приложение). Просто запретите события по умолчанию (используя e.preventDefault) в обработчике отправки формы. Вы можете использовать API истории HTML5, чтобы добавить что-нибудь в историю, чтобы указать, что вы "перемещались" внутри своего одностраничного приложения. Теперь браузер предложит сохранить пароль и имя пользователя.
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 (это тоже работает).

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

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

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

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

  • Chrome 39.0.2171.99m: РАБОТАЕТ
  • Android Chrome 39.0.2171.93: РАБОТАЕТ
  • Android-браузер Android (Android 4.4): НЕ РАБОТАЕТ
  • Internet Explorer 5+ (эмулированный): РАБОТАЕТ
  • Internet Explorer 11.0.9600.17498 / Update-версия: 11.0.15: РАБОТАЕТ
  • Firefox 35.0: РАБОТАЕТ

JS-Fiddle:
http://jsfiddle.net/ocozggqu/

Пост-код:

// modified post-code from https://stackru.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 требуется поле "пароль" для отображения диалогового окна store-password
  • Похоже, что 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, но мне это не удалось.

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

      <form id='login' action='javascript:login()'>
    <input type='text' name='username'> // required for Safari
    <input type='password'> // required for Chrome
    <button type='submit' form='login'>Log In</button>
</form>

Работало для Chrome, Firefox и Safari.

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

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

ех.

$(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 (хотя это работало в других браузерах).

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

Я пробовал все способы. Полностью ничего не работает. Это мое решение. Меня устраивает. Я надеюсь, что это сработает для вас. Я заменяю ввод электронной почты/имени пользователя текстовым полем

      <form>
<textarea required placeholder="Email" rows=1></textarea>
<input required placeholder="Password" type="password" readonly onfocus="this.removeAttribute('readonly')" />
<button>
    Sign in
</button>

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

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

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

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

Одна вещь, которую вы можете сделать, - это (после успешного входа пользователя) сохранить информацию о пользователе с помощью cookie и иметь опцию "Запомнить меня на этом компьютере". Таким образом, когда пользователь снова приходит (даже если он вышел из системы), ваше веб-приложение может извлечь файл 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, вам нужно обработать форму входа с помощью PHP.

Другие вопросы по тегам