期待される結果:テキストエリアに入力されたコンテンツはまだそこにあるはずです
実結果:
HTTPSを使用するとなぜこれが起こるのですか?どうすればこれを防ぐことができますか?ブラウザまたはウェブサイトは責任がありますか?
次のソリューションを検討できます。
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備考:
入力データは、ページリダイレクトの直前、またはすべてのフォームコントロールのfocus-outイベントにローカルに保存できます。
この場合、古き良きCookieは便利ですが、欠点を考慮する必要があります。
Http-Only
およびSecure
でマークされたCookieはここでは役に立ちません。これらのオプションは、Cookieが「送信」(安全)され、JavaScript(httpのみ)からアクセスできない場合にSSLを強制するために使用されるためです。maxlength
属性を介してコントロールの値を制限することによって);それが問題になる可能性があります。 (この場合、値のトリミングは最悪です)。それでも、明るい面は、すべてのブラウザーでサポートされていることであり、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 の「cookies reader/writer」スクリプトは、上記のコード。 Yahooの YUI 2: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()
});
これはほとんど同じように機能します。 W3Cから:sessionStorageオブジェクトは、1つのセッションのデータのみを格納することを除いて、localStorageオブジェクトと同じです。
あまり効率的な方法ではありませんが、他の方法が実行できない場合に使用することをお勧めします。 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...";
});
君に言っておく;たとえば、ユーザーが「更新」フォームに入力している場合。以前に保存したデータをサーバーからいつでもフェッチして、フォームに入力することができます(重要でないフィールド)。
あなたが本当にこれを必要とし、トラブルに値する場合;フォールバックメカニズムを実装するクロスブラウザソリューションを検討する必要があります。といった:
autocomplete
attributeを使用します。 (事前にHTMLに属性を埋め込むか、ブラウザーのサポートをテストするときにJavaScript/jQueryを介して設定できます。)Storage
オブジェクトをサポートしている場合。 localStorage
を使用します。cookies
を使用します。注:HTML5機能の検出については、 このページ または このページ をご覧ください。または、 Modernizr を使用できます。
HTTPSの問題:
[〜#〜] https [〜#〜]を使用すると、すべてのフォームの変更が失われるのはそのためです。 セキュアプロトコルです。フォームは主にユーザー入力に使用され、(おそらく)機密データを含めることができます。したがって、この動作は自然で予期されているようです。上記で提供するソリューションは、HTTPで行うのと同じように機能します。したがって、これですべての懸念がカバーされます。