JS页面刷新保持数据不丢失
转自:https://blog.csdn.net/qq_32439101/article/details/78134877
- 下面是 DOM Storage 的接口定义:
- interface Storage {
- readonly attribute unsigned long length;
- getter DOMString key(in unsigned long index);
- getter any getItem(in DOMString key);
- setter creator void setItem(in DOMString key, in any data);
- deleter void removeItem(in DOMString key);
- void clear();
- };
HTML5 是下一代 HTML 标准,开始吸引越来越多人的目光。HTML5 的 DOM Storage 机制提供了一种方式让程序员能够把信息存储到本地的计算机上,在需要时获取。这点和 cookie 相似,区别是 DOM Storage 提供了更大容量的存储空间。
目前,在客户端保存数据使用最多的是 cookie,但 cookie 的大小上限为 4KB,并且每次请求一个新页面时 cookie 都会被发送过去。更多的存储空间需要浏览器本身或是插件的支持,例如只在 Internet Explorer 上使用的 userData,需要额外安装插件的 Google Gears 和 Flash。现在,HTML5 提供了一种标准的接口,使程序员可以简单地访问存储的数据。由于键值对存储在本地计算机上,在页面加载完毕后可以通过 JavaScript 来操作这些数据。
DOM Storage
示例应用程序:用户注册
本文使用的示例应用程序是一个简单的用户注册过程,表单包含三个字段:name、age 和 address,我们将其拆分为两个表单,分两个页面显示。借助简化了的数据模型,主要介绍如何利用 DOM Storage 功能处理表单跨页问题。
DOM Storage 两个分类
DOM Storage 分为 sessionStorage 和 localStorage。
localStorage 对象和 sessionStorage 对象使用方法基本相同,它们的区别在于作用的范围不同。sessionStorage 用来存储与页面相关的数据,它在页面关闭后无法使用。而 localStorage 则持久存在,在页面关闭后也可以使用。
DOM Storage 接口
下面是 DOM Storage 的接口定义:
interface Storage {
readonly attribute unsigned long length;
getter DOMString key(in unsigned long index);
getter any getItem(in DOMString key);
setter creator void setItem(in DOMString key, in any data);
deleter void removeItem(in DOMString key);
void clear();
};
length:返回当前存储在 Storage 对象中的键值对数量。
key(index):返回列表中第 n 个键的名字。Index 从 0 开始。
getItem(key):返回指定键对应的值。
setItem(key, value):存入一个键值对。
removeItem(key) :删除指定的键值对。
clear():删除 Storage 对象中的所有键值对。
通常,使用最多的方法是 getItem 和 setItem。
以 sessionStorage 为例:
存储键值对:
window.sessionStorage.setItem(“key1”, value1);
通过键名来读取值:
var value1 = window.sessionStorage.getItem(“key1”);
判断浏览器是否支持 DOM Storage
要使用 DOM Storage,首先,需要查看当前的浏览器是否支持。目前 Internet Explorer 8.0 以上,Firefox 3.5 以上,Chrome 4.0 以上都是支持 DOM Storage 的。
如果浏览器不支持 DOM Storage,可以用其他的方法作为备选,本文还使用 Dojo 提供的 dojox.storage 模块来实现相同的功能。
清单 1. 查看浏览器是否支持 DOM Storage
- //sessionStorage
- if(window.sessionStorage){
- alert(“support sessionStorage”);
- }else{
- alert(“not support sessionStorage”);
- // 不支持 sessionStorage
- // 用 dojox.storage 来实现相同功能
- }
- //localStorage
- if(window.localStorage){
- alert(“support localStorage”);
- }else{
- alert(“not support localStorage”);
- // 不支持 localStorage
- // 用 dojox.storage 来实现相同功能
- }
下面是用户注册的两个表单。清单 2 中的第一个表单有两个字段 name 和 age 需要用户填写内容。填写完后点击 Next 按钮进入下一个页面,此时函数 saveToStorage 会被调用,把在该页面输入的两个字段的值保存到 sessionStorage 对象中。
当从下一个页面退回到本页面时,使用 windows.onload 在加载页面的时候将数据从 sessionStorage 中取出,并显示在输入框中,方便用户修改。
另外,给对象赋值除了用 setItem 方法外,也可以用 window.sessionStorage.key1 = “value1”。
清单 2. 第一个表单页面
- <script type="text/javascript">
- // 当退回到第一个页面时,从 sessionStorage 得到用户之前输入的值并显示在页面,方便修改
- window.onload = function(){
- if (window.sessionStorage) {
- var name = window.sessionStorage.getItem("name");
- var age = window.sessionStorage.getItem("age");
- if (name != "" || name != null){
- document.getElementById("name").value = name;
- }
- if (age != "" || age != null){
- document.getElementById("age").value = age;
- }
- }else
- {
- // 不支持 sessionStorage,用 Dojo 实现相同功能
- }
- };
- // 将数据保存到 sessionStorage 对象中
- function saveToStorage() {
- //sessionStorage
- if (window.sessionStorage) {
- var name = document.getElementById("name").value;
- var age = document.getElementById("age").value;
- window.sessionStorage.setItem("name", name);
- window.sessionStorage.setItem("age", age);
- window.location.href="form2.html";
- } else {
- // 不支持 sessionStorage,用 Dojo 实现相同功能
- }
- }
- </script>
- <form action="./form2.html">
- <input type="text" name="name" id="name">
- <input type="text" name="age" id="age">
- <input type="button" value="Next" onclick="saveToStorage()"></input>
- </form>
清单 3 的第二个页面有一个 address 字段。当用户填写完毕后,点击 Submit 按钮提交页面,此时 addStorageValue 函数被调用,把保存在 sessionStorage 中的 name 和 age 值先赋给当前表单的两个隐藏字段,随后一起提交给下一个处理表单的页面。最后调用 removeItem 函数删除 name 和 age 值。
如果用户需要修改第一个页面填写的内容,可以点击 Back 按钮回到前一个页面,用户在前一个页面已经填写的内容会出现在 text 框中。
清单 3. 第二个表单页面
- <script type="text/javascript">
- // 将保持在 sessionStorage 中的数据赋给表单的隐藏属性
- function addStorageValue() {
- //sessionStorage
- if (window.sessionStorage) {
- var name = window.sessionStorage.getItem("name");
- var age = window.sessionStorage.getItem("age");
- document.getElementById("name").value = name;
- document.getElementById("age").value = age;
- window.sessionStorage.removeItem("name");
- window.sessionStorage.removeItem("age");
- } else {
- // 不支持 sessionStorage,用 Dojo 实现相同功能
- }
- }
- function backToPreviousForm() {
- window.location.href="form1.html";
- }
- </script>
- <form action="./form3.php" method="post">
- <input type="hidden" name="name" id="name">
- <input type="hidden" name="age" id="age">
- <input type="text" name="address" id="address">
- <input type="button" value="Back" onclick="backToPreviousForm()">
- <input type="submit" value="Submit" onclick="addStorageValue()"></input>
- </form>
使用 DOM Storage 需要注意的几点
保存在 Storage 对象的数据类型
当使用 DOM Storage 进行本地存储时,任何数据格式在 Storage 对象中都以字符串类型保存,所以如果保存的数据不是字符串,在读取的时候需要自己进行类型的转换。这里我们使用 JSON 将对象序列化之后再存储。
JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写,同时也易于机器解析和生成。目前,JSON 已经是 JavaScript 标准的一部分,主流的浏览器对 JSON 支持都非常完善。
本文用到两个相关的函数
JSON.parse() 函数会把 JSON 对象转换为原来的数据类型。
JSON.stringify() 函数会把要保存的对象转换成 JSON 对象保存。
在清单 4 中,先把一个布尔型的数据存到 Storage 对象中,然后再取出,可以看到布尔类型的数据在取出的时候变为字符串。接下来换一种方式保存数据,先用 JSON.stringify 方法序列化数据,然后保存到 Storage 对象中,在取出的时候用 JSON.parse 方法进行反序列化,可以看到读取出的数据还是布尔类型。
另外,使用 JSON 保存一个字符串,通过 Chrome 的 Storage 工具,可以看到存入的字符串两边有双引号,这个双引号表示存入的是一个字符串。当用 JSON 表示一个简单的字符串时,会在字符串两边加上双引号。最后,该页面加载后的输出如下:
string1 boolean2 string3
- 清单 4. 使用 JSON 对 DOM Storage 的复杂数据进行处理
- // 生成一个 Boolean 类型的变量 data1
- var data1 = new Boolean(true);
- // 不用 JSON 处理数据
- sessionStorage["key1"] = data1;
- if(sessionStorage["key1"] == "true"){
- // 从 Storage 对象读取出来的数据 data1 变为 String 类型
- document.write("string1 ");
- }
- // 使用 JSON 处理数据 data1
- sessionStorage["key2"] = JSON.stringify(data1);
- if(JSON.parse(sessionStorage["key2"]) == true){
- // 从 Storage 对象读取的数据 data1,用 JSON 将变量转换为原来的 Boolean 类型
- document.write("boolean2 ");
- }
- // 生成一个 String 类型的变量
- var data2 = new String("true");
- // 使用 JSON 处理数据,在 Storage 对象中保存的是 “string”
- sessionStorage["key3"] = JSON.stringify(data2);
- data2 = JSON.parse(sessionStorage["key3"]);
- if(data2 == "true"){
- // 变量转换回来还是 String 类型
- document.write("string3");
- }
使用 Chrome 浏览器可以查看当前的 sessionStorage 和 localStorage 的键值对。在工具栏选择“工具”到“开发人员工具”到“Resources”到“Local Storage”或“Session Storage”, 可以查看 key 和 value。
图 1. Chrome 浏览器的 Storage 工具栏
综上所述,我们可以如清单 5 一样,在加载页面的时候用 JSON 转换数据类型,在离开页面的时候将数据保存为 JSON 对象。这样,保存在 Storage 中任何类型的数据在读取的时候都可以转换为原来的类型。
清单 5. 使用 JSON 对 DOM Storage 的复杂数据进行处理
- <script type="text/javascript">
- var value;
- function loadValue() {
- value1 = JSON.parse(window.sessionStorage.getItem(“key1”));
- }
- function saveValue() {
- window.sessionStorage.setItem(“key1”) = JSON.stringify(value1);
- }
- window.addEventListener(“load”, loadValue. true);
- window.addEventListener(“unload”, saveValue. true);
- </script>
空间大小
HTML5 的建议是每个网站提供给 Storage 的空间是 5MB,一般来说足够存字符串。如果存入的数据太大,有些浏览器如 Chrome 会抛出 QUOTA_EXCEEDED_ERR 异常。所以虽然 DOM Storage 提供的空间比 cookie 要大很多,但在使用需要注意限制。
图 2. Chrome 浏览器抛出异常
安全性
一般不要在客户端存储敏感的信息,使用 localStorage、globalStorage 等在客户端存储的信息都非常容易暴露。应该在完成数据存储后使用 clear 或者 removeItem 方法清除保存在 Storage 对象中的数据。
存储事件驱动
如果想在存储成功或修改存储的值时执行一些操作,可以用 DOM Storage 接口提供的事件。可以使用如下方法注册事件:
window.addEventListener(“storage”, handleStorageEvent, false);
存储事件接口定义
interface StorageEvent : Event {
readonly attribute DOMString key;
readonly attribute any oldValue;
readonly attribute any newValue;
readonly attribute DOMString url;
readonly attribute Storage storageArea;
void initStorageEvent(in DOMString typeArg, in boolean canBubbleArg,
in boolean cancelableArg, in DOMString keyArg, in any oldValueArg,
in any newValueArg, in DOMString urlArg, in Storage storageAreaArg);
};
key:发生改变的键。
oldValue:键改变之前的值。
newValue:键改变之后的值。
url:触发存储事件的页面 url。
在清单 6 中注册完存储事件后,当 sessionStorage 或者 localStorage 对象的值发生改变时,会触发 handleStorageEvent 函数,在页面显示发生改变的键和改变之前与之后的值。
清单 6. 添加存储事件
// 显示存储事件的相关内容
function handleStorageEvent(e) {
document.write(“key” + e.key + “oldValue” + e.oldValue + “newValue” + e.newValue);
}
// 添加存储事件监听
window.addEventListener(“storage”, handleStorageEvent, false);
使用 Dojo 实现之前用户注册的功能
Dojo 是一个 JavaScript 实现的开源工具包,很大程度上屏蔽了浏览器之间的差异性。Dojo 扩展库 (dojox) 是 Dojo 在其基本库、核心库和 Dijit 库的基础上提供的一个非常丰富的组件仓库。本文用到的 dojox.storage 模块能够将数据保存在本地存储中,实现和之前 DOM Storage 一样的功能。
由于一些老版本浏览器不支持 HTML5,我们还可以用 Dojo 来实现之前用户注册的功能。相对于 HTML5 的 DOM Storage 接口,Dojo 的 dojox.storage.Provider 接口提供的方法更多。这里我们列出几个常用的方法。
get(key, namespace):返回指定键对应的值。
put(key, value, resultsHandler, namespace):存入一个键值对。
remove(key, namespace):删除指定的键值对。
clear(namespace):删除对象中的所有键值对。
现在对第一个表单的 JavaScript 代码做部分修改,并在页面中引入 dojox.storage 模块。这样,程序在不支持 HTML5 的浏览器中能够通过调用 Dojo 提供的方法正常运行。dojo.require("dojox.storage") 表示引入 dojox.storage 功能模块。然后通过 dojox.storage.manager.isInitialized() 查看 dojox.storage.manager 是否已经初始化,如果没有的话,则需要等待其初始化完成之后,再进行存储操作。
清单 7. 经过修改后的第一个表单页面的部分代码
<script type="text/javascript">
dojo.require("dojox.storage");
// 当退回到第一个页面时,从 Storage 中得到用户之前输入的值并显示在页面,方便修改
// 这里先进行 dojox.storage.manager 的初始化
if(!dojox.storage.manager.isInitialized()){
dojo.connect(dojox.storage.manager, "loaded", saveAndLoad);
} else{
dojo.connect(dojo, "loaded", saveAndLoad);
}
function saveAndLoad(){
var name;
var age;
//sessionStorage
if (window.sessionStorage) {
name = window.sessionStorage.getItem("name");
age = window.sessionStorage.getItem("age");
if (name != "" || name != null){
document.getElementById("name").value = name;
}
if (age != "" || age != null){
document.getElementById("age").value = age;
}
}//dojox.storage
else
{
name = dojox.storage.get("name");
age = dojox.storage.get("age");
if (typeof name != "undefined" ){
document.getElementById("name").value = name;
}
if (typeof age != "undefined" ){
document.getElementById("age").value = age;
}
}
} // 保存数据
function saveToStorage() {
var name = document.getElementById("name").value;
var age = document.getElementById("age").value;
//sessionStorage
if (window.sessionStorage) {
window.sessionStorage.setItem("name", name);
window.sessionStorage.setItem("age", age);
}//dojox.storage
else {
dojox.storage.put("name", name);
dojox.storage.put("age", age);
}
window.location.href="form2.html";
}
</script>
清单 8. 经过修改后的第二个表单页面的部分代码
<script type="text/javascript">
dojo.require("dojox.storage");
// 将保存在 sessionStorage 中的数据赋给表单的隐藏属性
function addStorageValue() {
var name;
var age;
//sessionStorage
if (window.sessionStorage) {
name = window.sessionStorage.getItem("name");
age = window.sessionStorage.getItem("age");
document.getElementById("name").value = name;
document.getElementById("age").value = age;
window.sessionStorage.removeItem("name");
window.sessionStorage.removeItem("age");
}//dojox.storage
else {
name = dojox.storage.get("name");
age = dojox.storage.get("age");
document.getElementById("name").value = name;
document.getElementById("age").value = age;
dojox.storage.remove("name");
dojox.storage.remove("age");
}
} function backToPreviousForm() {
window.location.href = "form1.html";
}
</script>
JS页面刷新保持数据不丢失的更多相关文章
- 使用sessionStorage解决vuex在页面刷新后数据被清除的问题
https://www.jb51.net/article/138218.htm 1.原因 2.解决方法 localStorage没有时间期限,除非将它移除,sessionStorage即会话,当浏览器 ...
- 页面刷新vuex数据消失问题解决方案 之 vuex中间件
之前我写了一篇用ES6 Proxy方案解决数据同步的文章 页面刷新vuex数据消失问题解决方案. 今天和同事沟通这个vuex数据还原问题,我说我的方法很奇异.聊着聊着,同事咋不用 store.sub ...
- vue项目刷新页面,使数据不丢失(sessionStorage、localStorage、cookie)
vue项目刷新页面时,存储在vuex中的数据会丢失,把他们存到stroage中可以保证不丢失.
- 页面刷新vuex数据消失问题解决方案
VBox持续进行中,哀家苦啊,有没有谁给个star. vuex是vue用于数据存储的,和redux充当同样的角色. 最近在VBox开发的时候遇到的问题,页面刷新或者关闭浏览器再次打开的时候数据归零.这 ...
- js页面刷新之实现定时刷新(定时器,meta)
测试页面的代码见上一篇博客 接下来进入正题-定时不断刷新页面的方法: 1.看到定时,很容易想到js的定时器: //第一种方法 //由于我们已经有了一个定时器,所以只要在定时器test中加入一句刷新页面 ...
- vue 使用localStorage解决vuex在页面刷新后数据被清除的问题
通常,我们在使用vue编写页面时,会需要使用vuex在组件间传递(或者说共同响应)同一个数据的变化.例如:用户的登录信息. 下面,我们使用传递用户登录信息的例子来一步步解决这个问题. 首先,我们的第一 ...
- 【vue】使用localStorage解决vuex在页面刷新后数据被清除的问题
通常,我们在使用vue编写页面时,会需要使用vuex在组件间传递(或者说共同响应)同一个数据的变化.例如:用户的登录信息. 下面,我们使用传递用户登录信息的例子来一步步解决这个问题. 首先,我们的第一 ...
- vue:vue页面刷新vuex数据消失问题
vuex中数据刷新页面消失问题:a页面请求的数据保存在vuex中,只要不刷新,那跳转到b页面里也可以用,但如果b页面刷新,那vuex里的数据就会消失,可以得解决方法:a页面用的数据a页面的生命周期函数 ...
- 页面刷新 vuex 数据重新被初始化
1.原因 vuex里用来存储的也只是一个全局变量,当页面刷新,该全局变量自然不存在了. 2.解决 使用localStorage存储一份 (1)storage.js /** * vuex localSt ...
随机推荐
- JavaScript的基础数据类型和表达式
Java Script的基础数据类型和表达式 基本的数据类型: number(数值)类型:可分为整数和浮点数 string(字符)类型:是用单引号“'”或者双引号“"”来说明的. boole ...
- Python 之re正则表达式
- @Override注解
@Override注解对于代码可读性的提升十分巨大 而且良好的可读性是一个优秀程序员必备的基础素养
- SolidWorks学习笔记(一)
一.草图绘制 1.简单命令 先直线后圆弧,几何约束.尺寸标定 2.圆周阵列 3.几何关系——对称 添加几何约束:圆弧相等.关于竖直中心线的对称 4.捕捉圆心 5.尺寸锁定,有圆弧的,先直后圆 6. 7 ...
- docker安装kong和kong-dashboard
1:docker安装遵循官方手册 2:安装kong 参考文档:https://getkong.org/install/docker/ 安装过程基本和文档一致,文档十分简单清晰. 但应注意,为了最新版k ...
- 6)STM32使用HAL库实现modbus的简单通讯
1.判断地址.校验 2.读取本机数据并校验打包 3.发送数据包 4.本机数据长度比要读取的长度短怎么办 4.校验错误怎么办
- TortoiseGit配置密钥的方法
TortoiseGit 使用扩展名为ppk的密钥,而不是ssh-keygen生成的rsa密钥.使用命令ssh-keygen -C "邮箱地址" -t rsa产生的密钥在Tortoi ...
- Codeforces Round #413(Div. 1 + Div. 2, combined)——ABCD
题目在这里 A.Carrot Cakes 乱七八糟算出两个时间比较一下就行了 又臭又长仅供参考 #include <bits/stdc++.h> #define rep(i, j, k) ...
- VNC Server Installation on CentOS 6.5
In my case I have a fresh installed CentOS6.5 Server on which I will be installing the VNC-server so ...
- xth 的玫瑰花(codevs 1360)
题目描述 Description 这天是rabbit 的生日前夕,Xth 来到花店,要给他的rabbit 买玫瑰花,为了保证质 量,他跟花店老板——小菜儿同学要求自己到花田采摘.小菜儿灰常希望早日见到 ...