ねえ、私は次のように動作するログインダイアログを持っているウェブアプリに取り組んでいます:
<form>
ではありません-ユーザー/パスはAJAXを介して送信されます問題は次のとおりです。ブラウザは通常の「このパスワードを保存しますか?はい/しない/今すぐしない」というメッセージを決して表示しません。
<div>
タグを「autocomplete = 'on'」で<form>
タグでラップしようとしましたが、違いはありませんでした。
ログインフローを大幅に変更することなく、ブラウザにパスワードの保存を提供することは可能ですか?
ありがとう、エリック
追伸私の質問に追加するために、私は間違いなくパスワードを保存するブラウザで作業しており、「このサイトでは決して」をクリックしたことはありません...これはブラウザではなく、ログインフォームであることを検出しない技術的な問題ですエラー:-)
この質問に対する完全な解決策を見つけました。 (Chrome 27およびFirefox 21でこれをテストしました)。
知っておくべきことが2つあります。
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でも機能することがわかります。したがって、このメソッドを使用することをお勧めします。
すでに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'
は、ユーザー名/パスワードの「オートコンプリート」を許可しないため、ログインフォームへのユーザー名/パスワードの復元に失敗します。
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>
このフォームには送信ボタンがなく、アクションフィールドがないため、ブラウザはパスワードの保存を提案しません。
ただし、ボタンを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ファイルに直接埋め込むとすぐに、すべてが魔法のように機能しました。
これは、ブラウザが既存のログインフォームがあることを認識している必要があるが、私のものがページに動的に挿入されるため、「実際の」ログインフォームが存在することを知らなかったためだと思います。
このソリューションは、コーディングフォーラムでエリックによって投稿された私のために働いた
プロンプトが表示されない理由は、ブラウザがページを物理的にリフレッシュしてサーバーに戻す必要があるためです。できるちょっとしたトリックは、フォームで2つのアクションを実行することです。最初のアクションはonsubmitで、Ajaxコードを呼び出します。また、フォームに非表示のiframeをターゲットにします。
コード:
<iframe src="ablankpage.htm" id="temp" name="temp" style="display:none"></iframe>
<form target="temp" onsubmit="yourAjaxCall();">
それによりプロンプトが表示されるかどうかを確認します。
エリック
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の成功コールバックでフォームを再度送信して、ブラウザーがそれをキャッチして表示することですパスワード保存のリクエスト。エラーハンドラなどを追加することもできます。
それが誰かに役立ったことを願っています。
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でも動作することがテストされています。
ブラウザは、フォームがログインフォームであることを検出できない場合があります。 この前の質問 の議論のいくつかによれば、ブラウザは<input type="password">
のようなフォームフィールドを探します。パスワードフォームフィールドはそれと同様に実装されていますか?
Edit:以下の質問に答えるために、Firefoxはform.elements[n].type == "password"
(すべてのフォーム要素を反復)でパスワードを検出し、ユーザー名フィールドを検出すると思いますパスワードフィールドの直前のテキストフィールドのフォーム要素を逆方向に検索します(詳細 here )。私の知る限り、ログインフォームは<form>
の一部である必要があります。そうでない場合、Firefoxはそれを検出しません。
私はこのスレッドのさまざまな答えを読むのに多くの時間を費やしました。私にとっては、実際には少し異なるものでした(関連していましたが、異なっていました)。 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>
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で動作することがテストされています。
次のコードはでテストされます
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
への呼び出しが必要です次に、サンプルの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
});
};
備考
私は同様の問題を抱えていました。ログインはajaxで行われましたが、ブラウザ(firefox、chrome、safariおよびIE 7-10)はフォーム(#loginForm)がajaxで送信されるとパスワードを保存しません。
SOLUTIONとして、ajaxによって送信されたフォームに非表示の送信入力(#loginFormHiddenSubmit)を追加し、ajax呼び出しが成功を返した後、非表示の送信入力へのクリックをトリガーします。更新に必要な任意の方法のページ。クリックは次の方法でトリガーできます。
jQuery('#loginFormHiddenSubmit').click();
非表示の送信ボタンを追加した理由は次のとおりです。
jQuery('#loginForm').submit();
IEにパスワードを保存することを提案しません(ただし、他のブラウザでは機能します)。
あなたのサイトはおそらくすでにリストにあり、ブラウザはパスワードの保存を要求しないように指示されています。 firefoxでは、[オプション]-> [セキュリティ]-> [サイトのパスワードを記憶する] [チェックボックス]-例外[ボタン]
@Michal Roharikの回答にもう少し情報を追加してください。
あなたのajax呼び出しが戻りURLを返す場合、form.submitを呼び出す前にjqueryを使用してフォームアクション属性をそのURLに変更する必要があります
例.
$(form).attr('action', ReturnPath);
form.submitted = false;
form.submit();