次の解決策を検討できます。
属性(autocomplete
HTML5)
フォームで「送信」された以前のユーザー入力に基づいautocomplete
た値でフィールドに入力するようにブラウザに指示するため、これは無関係のようです。しかし、私のテストではそれを見ました。送信せずにフォームに記入した後。進む(履歴)ボタンを押して、もう一度押すと、設定するとフォームフィールドが自動入力され、に設定するとすべてクリアされました。autocomplete="on"
"off"
それで; (HTML5ユーザーを対象とする場合)この属性を使用して、フォームデータを「キャッシュ」できます。(Operaを除くすべての主要なブラウザで動作します)。
<form action="/update" method="post" autocomplete="on">
Email: <input type="text" id="email" /><br />
Username: <input type="text" id="uname" /><br />
Password: <input type="password" id="pwd" autocomplete="off"/><br />
<input type="submit" />
</form>
残りのフォームコントロールがオンの場合、特定のフィールド(この場合はパスワード)のオートコンプリート機能をオフに設定できることに注意してください。
MSDN備考:
- オートコンプリート属性がない場合、要素に親フォームがない場合、またはフォームのオートコンプリートが「オン」に設定されている場合、フィールドはデフォルトで「オン」状態になります。
- オートコンプリート機能によって提供される情報は、オブジェクトモデルに公開されず、ユーザーがテキストフィールドの値として提案の1つを選択するまで、Webページに表示されません。
未送信のフォームデータをローカルに保存します。
入力データは、ページリダイレクトの直前、またはすべてのフォームコントロールのフォーカスアウトイベントでローカルに保存できます。
クッキー
この場合、古き良きCookieが便利ですが、欠点を考慮する必要があります。
- プログラムで値を暗号化できますが、クライアント側で作業するため、Cookieはこれに対して本当に安全ではありません。
Http-Only
マークさSecure
れたCookieは、Cookieが「送信」(安全)でJavascript(httpのみ)からアクセスできない場合にSSLを適用するために使用されるため、ここでは役に立ちません。
- ブラウザにはCookieのサイズ制限があります。MSDNから:「ほとんどのブラウザは最大4096バイトのCookieをサポートしています。この小さな制限のため、Cookieは少量のデータを保存するために最適に使用されます」。したがって、このサイズを監視しない場合(Cookieを書き込むとき、および/または
maxlength
属性を介してコントロールの値を制限することによって)。それは問題になる可能性があります。(この場合、値のトリミングは最悪です)。
- ブラウザには、ドメインごとに設定できるCookieの数にも制限があります。それで; フォームデータをCookieに保存する場合。フォームフィールドの値ごとにCookieを設定する代わりに; それらを1つまたはいくつかのCookieにマージする必要があります。サイトがこの制限を超えないようにします。
それでも、明るい面は、すべてのブラウザでサポートされていることです。Cookieを介して機密性の高い長すぎるデータを「キャッシュ」する予定がない場合は、次のソリューションを使用できます。そうでない場合; 次の提案を行う方がよいでしょう:localStorage
。
// Below is just a demonstration and is not tested thoroughly for
// production-ready web applications by any means.
// But it should give you an idea.
/**
* Caches the user-input data from the targeted form, stores it in the cookies
* and fetches back to the form when requested or needed.
*/
var formCache = (function () {
var _form = null,
_formData = [],
_strFormElements = "input[type='text'],"
+ "input[type='checkbox'],"
+ "input[type='radio'],"
// + "input[type='password']," // leave password field out
+ "input[type='hidden'],"
// + "input[type='image'],"
+ "input[type='file'],"
// more input types...
+ "input[type='email'],"
+ "input[type='tel'],"
+ "input[type='url'],"
+ "select,"
+ "textarea";
function _warn() {
console.log('formCache is not initialized.');
}
return {
/**
* Initializes the formCache with a target form (id).
* You can pass any container id for the formId parameter, formCache will
* still look for form elements inside the given container. If no form id
* is passed, it will target the first <form> element in the DOM.
*/
init: function (formId) {
var f = (typeof formId === 'undefined' || formId === null || $.trim(formId) === '')
? $('form').first()
: $('#' + formId);
_form = f.length > 0 ? f : null;
console.log(_form);
return formCache; // make it chainable
},
/**
* Stores the form data in the cookies.
*/
save: function () {
if (_form === null) return _warn();
_form
.find(_strFormElements)
.each(function() {
var f = $(this).attr('id') + ':' + formCache.getFieldValue($(this));
_formData.push(f);
});
docCookies.setItem('formData', _formData.join(), 31536e3); // 1 year expiration (persistent)
console.log('Cached form data:', _formData);
return formCache;
},
/**
* Fills out the form elements from the data previously stored in the cookies.
*/
fetch: function () {
if (_form === null) return _warn();
if (!docCookies.hasItem('formData')) return;
var fd = _formData.length < 1 ? docCookies.getItem('formData').split(',') : _formData;
$.each(fd, function (i, item) {
var s = item.split(':');
var elem = $('#' + s[0]);
formCache.setFieldValue(elem, s[1]);
});
return formCache;
},
/**
* Sets the value of the specified form field from previously stored data.
*/
setFieldValue: function (elem, value) {
if (_form === null) return _warn();
if (elem.is('input:text') || elem.is('input:hidden') || elem.is('input:image') ||
elem.is('input:file') || elem.is('textarea')) {
elem.val(value);
} else if (elem.is('input:checkbox') || elem.is('input:radio')) {
elem.prop('checked', value);
} else if (elem.is('select')) {
elem.prop('selectedIndex', value);
}
return formCache;
},
/**
* Gets the previously stored value of the specified form field.
*/
getFieldValue: function (elem) {
if (_form === null) return _warn();
if (elem.is('input:text') || elem.is('input:hidden') || elem.is('input:image') ||
elem.is('input:file') || elem.is('textarea')) {
return elem.val();
} else if (elem.is('input:checkbox') || elem.is('input:radio')) {
return elem.prop('checked');
} else if (elem.is('select')) {
return elem.prop('selectedIndex');
}
else return null;
},
/**
* Clears the cache and removes the previously stored form data from cookies.
*/
clear: function () {
_formData = [];
docCookies.removeItem('formData');
return formCache;
},
/**
* Clears all the form fields.
* This is different from form.reset() which only re-sets the fields
* to their initial values.
*/
clearForm: function () {
_form
.find(_strFormElements)
.each(function() {
var elem = $(this);
if (elem.is('input:text') || elem.is('input:password') || elem.is('input:hidden') ||
elem.is('input:image') || elem.is('input:file') || elem.is('textarea')) {
elem.val('');
} else if (elem.is('input:checkbox') || elem.is('input:radio')) {
elem.prop('checked', false);
} else if (elem.is('select')) {
elem.prop('selectedIndex', -1);
}
});
return formCache;
}
};
})();
// Save form data right before we unload the form-page
$(window).on('beforeunload', function (event) {
formCache.save();
return false;
});
// Initialize and fetch form data (if exists) when we load the form-page back
$(document).on('ready', function (event) {
formCache.init().fetch();
});
これがjsFiddleの動作デモです。
注:developer.mozilla.orgの「cookiesreader / writer」スクリプトは、上記のコードに含まれている必要があります。YahooのYUI2 :Cookieユーティリティを使用することもできます。これは、前述のブラウザの制限に対して、単一のCookie内にサブCookieを設定するための便利なsetSub()メソッドを備えています。
ローカルストレージ
localStorage
(HTML5)のような最新の手法を使用することもできます。より安全で高速です。IE 8以降を含むすべての主要なブラウザーは、この機能をサポートしています。(さらに、iOSとAndroidのサポート!)
if (typeof Storage !== 'undefined') { // We have local storage support
localStorage.username = 'Onur'; // to save to local storage
document.getElementById('uname').value = localStorage.username; // to fetch from local storage
}
したがって、Cookieの例のように。
$(window).on('beforeunload', function (event) {
saveFormToLocalStorage();
return false;
});
$(document).on('ready', function (event) {
fillFormFromLocalStorage()
});
SessionStorage
これはほとんど同じように機能します。W3Cから:sessionStorageオブジェクトは、1つのセッションのデータのみを格納することを除いて、localStorageオブジェクトと同じです。
サイレントAJAX投稿を介してフォームデータをサーバー/DBに保存します。
あまり効率的な方法ではありませんが、他の人が実行できない場合にこれを使用することをお勧めします。イベントに投稿してbeforeunload
、ユーザーにメッセージを表示することができます。
$(window).on('beforeunload', function (event) {
//check if at least one field is filled out.
//make the AJAX post if filled out.
return "You are leaving the page without submitting the form...";
});
ページの読み込み時にサーバーから以前に保存したデータを取得する:
君に言っておく; たとえば、ユーザーが「更新」フォームに入力している場合。以前に保存したデータをサーバーからいつでも取得して、フォームに自動的に入力できます(機密性の低いフィールド)。
結論
あなたが本当にこれを必要とし、トラブルの価値があるなら; フォールバックメカニズムを実装するクロスブラウザソリューションを検討する必要があります。そのような:
- HTML5機能をサポートしている場合。HTML5
autocomplete
属性を使用します。(事前にHTMLに属性を埋め込むか、ブラウザーのサポートをテストするときにJavascript / jQueryを介して属性を設定できます。)
Storage
それ以外の場合、オブジェクトをサポートしている場合。と一緒に行く
localStorage
;
- ELSEIF[現在のセッションが保存するCookie]+[フォームデータに必要なCookieサイズ]<4096バイト; 次に、を使用します
cookies
。
- それ以外の場合、サーバー側のWebアプリがある場合は、サーバーにデータを保存するためのサイレントAJAXリクエストを
作成します。
- それ以外の場合は行いません。
注: HTML5機能の検出については、このページまたはこのページを参照するか、 Modernizrを使用できます。
HTTPSの問題:
その理由は、 HTTPSを使用すると、すべてのフォームの変更がなくなるためです。これは安全なプロトコルです。フォームは主にユーザー入力に使用され、(おそらく)機密データを含めることができます。したがって、この動作は自然で予想されるもののようです。上記で提供したソリューションは、HTTPの場合と同じように機能します。だから、それはあなたのすべての懸念をカバーするはずです。
参考文献: