web-dev-qa-db-ja.com

ブラウザにパスワードを保存するよう促すにはどうすればよいですか?

ねえ、私は次のように動作するログインダイアログを持っているウェブアプリに取り組んでいます:

  1. ユーザーが「ログイン」をクリックします
  2. ログインフォームHTMLはAJAXでロードされ、ページのDIVに表示されます
  3. ユーザーはフィールドにユーザー/パスを入力し、送信をクリックします。 <form>ではありません-ユーザー/パスはAJAXを介して送信されます
  4. ユーザー/パスに問題がない場合、ユーザーがログインした状態でページがリロードされます。
  5. ユーザー/パスに問題がある場合、ページは再読み込みされませんが、DIVにエラーメッセージが表示され、ユーザーは再試行します。

問題は次のとおりです。ブラウザは通常の「このパスワードを保存しますか?はい/しない/今すぐしない」というメッセージを決して表示しません。

<div>タグを「autocomplete = 'on'」で<form>タグでラップしようとしましたが、違いはありませんでした。

ログインフローを大幅に変更することなく、ブラウザにパスワードの保存を提供することは可能ですか?

ありがとう、エリック

追伸私の質問に追加するために、私は間違いなくパスワードを保存するブラウザで作業しており、「このサイトでは決して」をクリックしたことはありません...これはブラウザではなく、ログインフォームであることを検出しない技術的な問題ですエラー:-)

129
Eric

この質問に対する完全な解決策を見つけました。 (Chrome 27およびFirefox 21でこれをテストしました)。

知っておくべきことが2つあります。

  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の場合、「パスワードの保存」がトリガーされますafterによってページにリダイレクトされます入力テキストフィールド属性名= 'username'および入力パスワードフィールド属性名= '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();を呼び出すと、サインインしているページにリダイレクトされます。サインインしているページが現在のページである場合、「signedIn.xxx」を現在のページに置き換えて「更新」することができます。

これで、Chrome 27のメソッドがFirefox 21でも機能することがわかります。したがって、このメソッドを使用することをお勧めします。

2。保存されたユーザー名/パスワードを復元します:

すでにHTMLとしてハードコーディングされたloginFormがある場合、loginFormに保存されたパスワードを復元しても問題はありません。
ただし、js/jqueryを使用してloginFormを動的に作成する場合、保存されたユーザー名/パスワードはドキュメントがロードされたときにのみバインドされるため、保存されたユーザー名/パスワードはloginFormにバインドされません。
したがって、loginFormをHTMLとしてハードコーディングし、js/jqueryを使用してloginFormを動的に移動/表示/非表示にする必要がありました。


備考:ajaxログインを行う場合は、次のようなタグ形式でautocomplete='off'を追加しないでください。

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

autocomplete='off'は、ユーザー名/パスワードの「オートコンプリート」を許可しないため、ログインフォームへのユーザー名/パスワードの復元に失敗します。

64
Timespace7

ボタンを使用してログインする:

onclickハンドラーでtype="button"を使用して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
}
40
spetson

私は自分でこれに苦労してきましたが、ようやく問題と失敗の原因を突き止めることができました。

それはすべて、私のログインフォームが(backbone.jsを使用して)ページに動的に挿入されたという事実に由来します。ログインフォームをindex.htmlファイルに直接埋め込むとすぐに、すべてが魔法のように機能しました。

これは、ブラウザが既存のログインフォームがあることを認識している必要があるが、私のものがページに動的に挿入されるため、「実際の」ログインフォームが存在することを知らなかったためだと思います。

15
TK421

このソリューションは、コーディングフォーラムでエリックによって投稿された私のために働いた


プロンプトが表示されない理由は、ブラウザがページを物理的にリフレッシュしてサーバーに戻す必要があるためです。できるちょっとしたトリックは、フォームで2つのアクションを実行することです。最初のアクションは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

12
Vincent

jQueryを使用してパスワードを保存するように要求するすべてのブラウザー(テスト済み:chrome 25、safari 5.1、IE10、Firefox 16)を強制するltimateソリューションがあります。および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の成功コールバックでフォームを再度送信して、ブラウザーがそれをキャッチして表示することですパスワード保存のリクエスト。エラーハンドラなどを追加することもできます。

それが誰かに役立ったことを願っています。

11
Michal Roharik

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でも動作することがテストされています。

7
w00t

ブラウザは、フォームがログインフォームであることを検出できない場合があります。 この前の質問 の議論のいくつかによれば、ブラウザは<input type="password">のようなフォームフィールドを探します。パスワードフォームフィールドはそれと同様に実装されていますか?

Edit:以下の質問に答えるために、Firefoxはform.elements[n].type == "password"(すべてのフォーム要素を反復)でパスワードを検出し、ユーザー名フィールドを検出すると思いますパスワードフィールドの直前のテキストフィールドのフォーム要素を逆方向に検索します(詳細 here )。私の知る限り、ログインフォームは<form>の一部である必要があります。そうでない場合、Firefoxはそれを検出しません。

4
bta

私はこのスレッドのさまざまな答えを読むのに多くの時間を費やしました。私にとっては、実際には少し異なるものでした(関連していましたが、異なっていました)。 Mobile Safari(iOSデバイス)では、ページの読み込み時にログインフォームが非表示の場合、プロンプトは表示されません(フォームを表示してから送信した後)。次のコードを使用してテストできます。このコードは、ページが読み込まれてから5秒後にフォームを表示します。 JSとディスプレイを削除します: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>
1
captainclam

Prototype.JSユーザー向けのかなりエレガントなソリューション(またはハックなど)を見つけました。これは、Prototypeを使用した最後のホールドアウトの1つです。対応する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()は、非表示の入力ボタンのクラスでEvent.findElementでラップされていない限り(上記のように、faux-submit)、DOMのすべての送信イベントを停止します。

document.observe('submit', function(event) {
    if (event.findElement(".faux-submit")) { 
        event.stop();
    }
});

これは、Firefox 43およびChrome 50で動作することがテストされています。

1
mwieczorek

次のコードはでテストされます

  • Chrome 39.0.2171.99m:WORKING
  • Android Chrome 39.0.2171.93:WORKING
  • Androidストックブラウザ(Android 4.4):機能していません
  • Internet Explorer 5+(エミュレート):WORKING
  • Internet Explorer 11.0.9600.17498/Update-Version:11.0.15:WORKING
  • 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ストアパスワードダイアログを表示するには「パスワード」フィールドが必要
  • Internet Explorerは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
    });
};

備考

  • 「アカウント/ログイン」は、成功した場合、cookieを設定します
  • Page-redirect(js-codeによって開始される「手動」)が必要なようです。 iframe-postもテストしましたが、うまくいきませんでした。
1

私は同様の問題を抱えていました。ログインはajaxで行われましたが、ブラウザ(firefox、chrome、safariおよびIE 7-10)はフォーム(#loginForm)がajaxで送信されるとパスワードを保存しません。

SOLUTIONとして、ajaxによって送信されたフォームに非表示の送信入力(#loginFormHiddenSubmit)を追加し、ajax呼び出しが成功を返した後、非表示の送信入力へのクリックをトリガーします。更新に必要な任意の方法のページ。クリックは次の方法でトリガーできます。

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

非表示の送信ボタンを追加した理由は次のとおりです。

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

IEにパスワードを保存することを提案しません(ただし、他のブラウザでは機能します)。

0
Igor

あなたのサイトはおそらくすでにリストにあり、ブラウザはパスワードの保存を要求しないように指示されています。 firefoxでは、[オプション]-> [セキュリティ]-> [サイトのパスワードを記憶する] [チェックボックス]-例外[ボタン]

0
Dave.Sol

@Michal Roharikの回答にもう少し情報を追加してください。

あなたのajax呼び出しが戻りURLを返す場合、form.submitを呼び出す前にjqueryを使用してフォームアクション属性をそのURLに変更する必要があります

例.

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