Onu*_*rım 67
您可以考虑以下解决方案:
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>
Run Code Online (Sandbox Code Playgroud)
请注意,当其他表单控件打开时,您可以为特定字段(在这种情况下为密码)设置自动完成功能.
MSDN备注:
您可以在页面重定向之前本地存储输入数据,也可以在每个表单控件的焦点输出事件中存储输入数据:
在这种情况下,好的旧饼干可以派上用场,但你应该考虑下方:
Http-Only和Secure标记的cookie对我们没有帮助,因为这些选项用于在"发送"(安全)cookie时强制执行SSL,并且无法从Javascript(仅限http)访问.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();
});
Run Code Online (Sandbox Code Playgroud)
这是关于jsFiddle的工作演示.
注意:developer.mozilla.org的"cookies reader/writer"脚本应包含在上面的代码中.您还可以使用Yahoo的YUI 2:Cookie Utility,它具有一个有用的setSub()方法,用于在单个cookie中设置子cookie,用于我之前提到的浏览器限制.
您还可以使用更多现代技术,如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
}
Run Code Online (Sandbox Code Playgroud)
所以,就像在cookies示例中一样;
$(window).on('beforeunload', function (event) {
saveFormToLocalStorage();
return false;
});
$(document).on('ready', function (event) {
fillFormFromLocalStorage()
});
Run Code Online (Sandbox Code Playgroud)
这几乎是一样的.从W3C:sessionStorage对象等于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...";
});
Run Code Online (Sandbox Code Playgroud)
提醒你一下; 如果用户填写"更新"表格,例如; 您始终可以从服务器获取以前保存的数据并自动填写表单(非敏感字段).
如果你真的需要这个并且值得麻烦; 您应该考虑实现回退机制的跨浏览器解决方案; 如:
autocomplete
属性.(您可以预先在HTML中嵌入该属性,或者在测试浏览器支持时通过Javascript/jQuery进行设置.)Storage对象的支持; 去
localStorage;cookies.注意:对于HTML5功能检测,请查看此页面或此页面,或者您可以使用Modernizr.
HTTPS问题:
原因是,使用HTTPS时所有表单更改都消失了; 这是一个安全的协议.表单主要用于用户输入,并且(可能)包含敏感数据.所以这种行为似乎是自然而且可取的 我上面提供的解决方案与HTTP上的解决方案相同.所以这应该涵盖你所有的担忧.