您可以考虑以下解决方案:
The 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”状态
自动完成设置为“打开”。
- 自动完成功能提供的信息不会暴露给
对象模型,并且在用户访问之前对网页不可见
选择建议之一作为文本字段的值。
将未提交的表单数据保存到本地:
您可以在页面重定向之前或每个表单控件的焦点移出事件之前将输入数据存储在本地:
Cookies
在这种情况下,老式饼干会派上用场,但您应该考虑其缺点:
- 即使您可以通过编程方式加密这些值;由于我们将在客户端工作,因此 cookie 对此并不真正安全。
Http-Only
and Secure
标记的 cookie 在这里对我们没有帮助,因为这些选项用于在 cookie 被“发送”(安全)并且无法从 Javascript(仅限 http)访问时强制执行 SSL。
- 浏览器有 cookie 大小限制。从MSDN: “大多数浏览器都支持
最多 4096 字节的 cookie。由于这个小限制,cookie
最好用于存储少量数据”。所以,如果你不这样做
注意这个大小(当你写cookie和/或通过限制
控件的值通过
maxlength
属性);那可能是一个
问题。 (在这种情况下,削减该值是最糟糕的事情)。
- 浏览器对可设置的 cookie 数量也有限制
每个域。所以;将表单数据存储在 cookie 中时;而不是为每个表单字段值设置cookie;您应该将它们合并为一个或几个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 上的工作演示 http://jsfiddle.net/onury/PJbye/.
Note:“cookies 读取器/写入器”脚本来自开发者.mozilla.org http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#autofilling-form-controls:-the-autocomplete-attribute应包含在上面的代码中。您还可以使用雅虎的YUI 2:Cookie 实用程序 http://developer.yahoo.com/yui/cookie/其中有一个有用的setSub() http://developer.yahoo.com/yui/cookie/#subcookies针对我之前提到的浏览器限制,在单个 cookie 中设置子 cookie 的方法。