Ответ 1
Вы можете рассмотреть следующие решения:
Атрибут 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 Примечания:
- Если атрибут автозаполнения отсутствует, по умолчанию будет установлено состояние 'on', если элемент не имеет родительской формы, или если форма имеет автозаполнение установлено на 'on'.
- Информация, предоставляемая функцией автозаполнения, не отображается объектной модели и не отображается на веб-странице до тех пор, пока пользователь выбирает одно из предложений в качестве значения для текстового поля.
Сохранять данные незаправленной формы локально:
Вы можете хранить входные данные локально, прямо перед перенаправлением страницы или событием фокуса для каждого элемента управления формой:
Cookies
В этом случае добрые старые куки могут пригодиться, но вы должны рассмотреть нижние стороны:
- Даже если вы можете шифровать значения программно; поскольку мы будем работать на стороне клиента, файлы cookie для этого не являются действительно безопасными.
Http-Only
иSecure
отмеченные файлы cookie не помогут нам здесь, потому что эти параметры используются для обеспечения SSL, когда cookie "отправляется" (защищен) и не может быть доступен из Javascript (только http). - У браузеров ограничение размера файлов cookie. От MSDN: "Поддержка большинства браузеров
файлы cookie до 4096 байт. Из-за этого небольшого ограничения файлы cookie
лучше всего использовать для хранения небольших объемов данных ". Итак, если вы не
следите за этим размером (когда вы пишете файл cookie и/или ограничиваете
контрольное значение через атрибуты
maxlength
); это может быть проблема. (и обрезка значения является наихудшей в этом случае). - Браузеры также имеют ограничение на количество файлов cookie, которые могут быть установлены. на домен. Так; при хранении данных формы в файлах cookie; вместо настройки файлов cookie для каждого значения поля формы; вы должны объединить их в одно или несколько файлов cookie; для вашего сайта не превышают этот предел.
Тем не менее, яркая сторона поддерживается всеми браузерами, и если вы не планируете "кэшировать" чувствительные и слишком длинные данные через Cookies, вы можете использовать следующее решение. Если это не так; вам лучше пойти со следующим предложением: 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.
Примечание. "Код чтения/записи cookie" script от developer.mozilla.org должен быть включен в код выше. Вы также можете использовать Yahoo YUI 2: Cookie Utility, который имеет полезный метод setSub() для настройки под- cookie внутри одного файла cookie, для ограничения браузера, о котором я упоминал ранее.
LocalStorage
Вы также можете использовать более современные методы, такие как 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
}
Итак, как в примере куки;
$(window).on('beforeunload', function (event) {
saveFormToLocalStorage();
return false;
});
$(document).on('ready', function (event) {
fillFormFromLocalStorage()
});
SessionStorage
Это работает почти так же. Из W3C: объект sessionStorage равен объекту localStorage, за исключением того, что он хранит данные только для одного сеанса.
Сохранение данных формы на сервер/БД через Silent AJAX Post (s):
Не очень эффективный способ, но вы можете использовать его там, где другие невозможны. Вы можете сделать сообщение в событии 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, когда вы проверяете поддержку браузера.) - ELSE Если у вас есть поддержка объекта
Storage
; идти сlocalStorage
- ELSE IF [файлы cookie текущих хранилищ] + [размер файла cookie
формы данных] 4096 байт; затем используйте
cookies
. - ELSE Если у вас есть веб-приложение на стороне сервера, сделайте тихие запросы AJAX хранить данные на сервере.
- ELSE этого не делает.
Примечание.. Для обнаружения функции HTML5 просмотрите эту страницу или эту страницу или вы можете использовать Modernizr.
Проблема с HTTPS:
Причина: все изменения формы исчезают при использовании HTTPS; это безопасный протокол . Формы в основном используются для ввода пользователем и могут (возможно) содержать конфиденциальные данные. Поэтому это поведение кажется естественным и ожидаемым. Решение (ы), которое я предлагаю выше, будет работать так же, как и для HTTP. Таким образом, это должно охватывать все ваши проблемы.