HTML5的5种存储方式详解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HTML5的5种存储方式详解相关的知识,希望对你有一定的参考价值。
参考技术A
引言
本篇文章主要介绍了前端HTML5几种存储方式的总结 ,主要包括本地存储localstorage,本地存储sessionstorage,离线缓存(application cache),Web SQL,IndexedDB。有兴趣的可以了解一下。
正文开始~
h5之前,存储主要是用cookies。cookies缺点有在请求头上带着数据,大小是4k之内。主Domain污染。
主要应用:购物车、客户登录
对于IE浏览器有UserData,大小是64k,只有IE浏览器支持。
目标
存储方式:
以键值对(Key-Value)的方式存储,永久存储,永不失效,除非手动删除。
大小:
每个域名5M
支持情况:
注意:IE9 localStorage不支持本地文件,需要将项目署到服务器,才可以支持!
常用的API:
getItem //取记录
setIten//设置记录
removeItem//移除记录
key//取key所对应的值
clear//清除记录
存储的内容:
数组,图片,json,样式,脚本。。。(只要是能序列化成字符串的内容都可以存储)
html5 的本地存储 API 中的 localStorage 与 sessionStorage 在使用方法上是相同的,区别在于 sessionStorage 在关闭页面后即被清空,而 localStorage 则会一直保存。
本地缓存应用所需的文件
使用方法:
①配置manifest文件
页面上:
Manifest 文件:
manifest 文件是简单的文本文件,它告知浏览器被缓存的内容(以及不缓存的内容)。
manifest 文件可分为三个部分:
①CACHE MANIFEST - 在此标题下列出的文件将在首次下载后进行缓存
②NETWORK - 在此标题下列出的文件需要与服务器的连接,且不会被缓存
③FALLBACK - 在此标题下列出的文件规定当页面无法访问时的回退页面(比如 404 页面)
完整demo:
服务器上: manifest文件需要配置正确的MIME-type,即 "text/cache-manifest"。
如Tomcat:
常用API:
核心是applicationCache对象,有个status属性,表示应用缓存的当前状态:
0(UNCACHED) : 无缓存, 即没有与页面相关的应用缓存
1(IDLE) : 闲置,即应用缓存未得到更新
2 (CHECKING) : 检查中,即正在下载描述文件并检查更新
3 (DOWNLOADING) : 下载中,即应用缓存正在下载描述文件中指定的资源
4 (UPDATEREADY) : 更新完成,所有资源都已下载完毕
5 (IDLE) : 废弃,即应用缓存的描述文件已经不存在了,因此页面无法再访问应用缓存
相关的事件:
表示应用缓存状态的改变:
checking : 在浏览器为应用缓存查找更新时触发
error : 在检查更新或下载资源期间发送错误时触发
noupdate : 在检查描述文件发现文件无变化时触发
downloading : 在开始下载应用缓存资源时触发
progress:在文件下载应用缓存的过程中持续不断地下载地触发
updateready : 在页面新的应用缓存下载完毕触发
cached : 在应用缓存完整可用时触发
Application Cache的三个优势:
① 离线浏览
② 提升页面载入速度
③ 降低服务器压力
注意事项:
1. 浏览器对缓存数据的容量限制可能不太一样(某些浏览器设置的限制是每个站点 5MB)
2. 如果manifest文件,或者内部列举的某一个文件不能正常下载,整个更新过程将视为失败,浏览器继续全部使用老的缓存
3. 引用manifest的html必须与manifest文件同源,在同一个域下
4. 浏览器会自动缓存引用manifest文件的HTML文件,这就导致如果改了HTML内容,也需要更新版本才能做到更新。
6. FALLBACK中的资源必须和manifest文件同源
7. 更新完版本后,必须刷新一次才会启动新版本(会出现重刷一次页面的情况),需要添加监听版本事件。
8. 站点中的其他页面即使没有设置manifest属性,请求的资源如果在缓存中也从缓存中访问
9. 当manifest文件发生改变时,资源请求本身也会触发更新
离线缓存与传统浏览器缓存区别:
1. 离线缓存是针对整个应用,浏览器缓存是单个文件
2. 离线缓存断网了还是可以打开页面,浏览器缓存不行
3. 离线缓存可以主动通知浏览器更新资源
关系数据库,通过SQL语句访问
Web SQL 数据库 API 并不是 HTML5 规范的一部分,但是它是一个独立的规范,引入了一组使用 SQL 操作客户端数据库的 APIs。
支持情况:
Web SQL 数据库可以在最新版的 Safari, Chrome 和 Opera 浏览器中工作。
核心方法:
①openDatabase: 这个方法使用现有的数据库或者新建的数据库创建一个数据库对象。
②transaction: 这个方法让我们能够控制一个事务,以及基于这种情况执行提交或者回滚。
③executeSql: 这个方法用于执行实际的 SQL 查询。
打开数据库:
执行查询操作:
插入数据:
读取数据:
由这些操作可以看出,基本上都是用SQL语句进行数据库的相关操作,如果你会mysql的话,这个应该比较容易用。
索引数据库 (IndexedDB) API(作为 HTML5 的一部分)对创建具有丰富本地存储数据的数据密集型的离线 HTML5 Web 应用程序很有用。同时它还有助于本地缓存数据,使传统在线 Web 应用程序(比如移动 Web 应用程序)能够更快地运行和响应。
异步API:
在IndexedDB大部分操作并不是我们常用的调用方法,返回结果的模式,而是请求——响应的模式,比如打开数据库的操作
这样,我们打开数据库的时候,实质上返回了一个DB对象,而这个对象就在result中。由上图可以看出,除了result之外。还有几个重要的属性就是onerror、onsuccess、onupgradeneeded(我们请求打开的数据库的版本号和已经存在的数据库版本号不一致的时候调用)。这就类似于我们的ajax请求那样。我们发起了这个请求之后并不能确定它什么时候才请求成功,所以需要在回调中处理一些逻辑。
关闭与删除:
数据存储:
indexedDB中没有表的概念,而是objectStore,一个数据库中可以包含多个objectStore,objectStore是一个灵活的数据结构,可以存放多种类型数据。也就是说一个objectStore相当于一张表,里面存储的每条数据和一个键相关联。
我们可以使用每条记录中的某个指定字段作为键值(keyPath),也可以使用自动生成的递增数字作为键值(keyGenerator),也可以不指定。选择键的类型不同,objectStore可以存储的数据结构也有差异。
学习从来不是一个人的事情,要有个相互监督的伙伴,想要学习或交流前端问题的小伙伴可以私信“学习”小明获取web前端入门资料,一起学习,一起成长!
Android数据存储----SharedPreferences详解
一、Android数据的存储方式:
Android系统一共提供了四种数据存储方式。分别是:SharePreference、SQLite、Content Provider和File;此外还有一种网络存储。由于Android系统中,数据基本都是私有的,都是存放于“data/data/程序包名”目录下,所以要实现数据共享,正确方式是使用Content Provider。
在Android中,可以使用几种方式实现数据持久化:
- Shared Preferences:除SQLite数据库外,另一种常用的数据存储方式。共享参数形式,一种以Key-Value的键值对形式保存数据的方式,其本质就是一个xml文件。Android内置的,一般应用的配置信息,推荐使用此种方式保存。
- Internal Storage:使用Android设备自带的内存存储数据。
- External Storage:使用外部存储设备存储数据,一般是指Sdcard。
- SQLite Databases:以SQLite数据库存储结构化的数据。SQLite是一个轻量级的数据库,支持基本SQL语法,是常被采用的一种数据存储方式。Android为此数据库提供了一个名为SQLiteDatabase的类,封装了一些操作数据库的API。
- Network Connection:使用基于网络的服务获取数据。
二、Android的文件系统:
1、Android系统文件目录:
2、Android的应用数据存储机制:
在Android中,第三方应用及其数据,都存放在data目录下。其中,应用安装包会被存放到/data/app/目录下,每个安装包的文件名都形如:应用包名.apk,以避免重复。比如包名为com.test.sample的应用,其应用数据的目录为/data/data/com.test.sample/。对应的数据库文件存储在/data/data/com.test.sample/database/目录下,设置文件存储在/data/data/com.test.sample/shared_prefs/,自定义的应用数据文件存储在目录/data/data/com.test.sample/files/下,等等。
不仅如此,Android还会为每个应用创建一个账号,只有通过本应用的账号才有权限去运行该应用的安装包文件,读写应用数据目录下的文件(当然root权限除外),从而保证了该应用数据不会再被其他应用获取或破坏。
3、Android的文件操作:
从应用数据目录下可以看出,数据文件可以分成两类,一类是放置在扩展存储器中的文件,即/sdcard/目录下的文件,它们可以被各个应用共享;而另一类则是放在该应用数据目录下文件,它们仅能被各个应用独享,不能被其他应用读写。
三、SharedPreferences:
在所有应用程序中,都必然涉及数据的交互。有些时候,应用程序有少量的数据需要保存,并且这些数据的格式很简单。比如:软件设置、用户账户设置,用户习惯设置等,这个时候就可以用到SharedPreferences。
其实,SharedPreferences使用xml格式为Android应用提供一种永久的数据存贮方式,并且是使用键值对的方式来存储数据的。对于一个Android应用,它存贮在文件系统的/data/data/your_app_package_name/shared_prefs/目录下,可以被处在同一个应用中的所有Activity 访问。Android 提提供了相关的API来处理这些数据而不需要程序员直接操作这些文件或者考虑数据同步的问题。
因为SharedPreferences本身是一个接口,程序无法直接创建SharedPreferences的实例,只能通过Context提供的getSharedPreferences(String name,int mode)方法来获取SharedPreferences的实例:
public abstract SharedPreferences getSharedPreferences(String name,int mode)
此方法接收两个参数,第一个参数用于指定SharedPreferences文件的名称(格式为xml文件),如果指定的文件不存在则会创建一个。SharedPreferences文件都是存放在/data/data/<packagename>/shared_prefs/目录下的;第二个参数用于指定操作模式:
- MODE_PRIVATE:默认操作模式,和直接传0效果相同,表示只有当前应用程序才可以对这个SharedPreferences文件进行读写
- MODE_WORLD_READABLE:指定此SharedPreferences对其他程序只读且无法修改。
- MODE_WORLD_WRITEABLE:指定此SharedPreferences能被其他程序读写。
- MODE_MULTI_PROCESS:Android2.3之后已经弃之不用了。
得到SharedPreferences对象后,就可以向SharedPreferences文件中存储数据了,主要分为以下三步:
- 调用SharedPreferences对象的edit()方法来获取一个SharedPreferences.Editor对象
- 向SharedPreferences.Editor对象中添加数据,比如添加一个布尔型数据就使用putBoolean方法,添加一个字符串就用putString()方法,以此类推
- 调用commit()方法将添加的数据提交,从而完成数据存储操作
三、实例:保存编辑的短信内容:
通常情况下会发生这样的问题,我们在编辑短信的同时有电话打进来,那么接电话肯定是要启动另一个Activiy,那么当前编辑短信的Activity所编辑的信息我们想暂时保存下来,等接完电话后回到该Activity时,可以继续编辑短信。该功能需要如何去实现呢?
(1)保存数据:
首先使用SharedPreferences这个工具类:
1 private EditText etMsg ; 2 private Button sendButton; 3 private SharedPreferences sp; 4 5 @Override 6 protected void onCreate(Bundle savedInstanceState) 7 super.onCreate(savedInstanceState); 8 setContentView(R.layout.activity_main); 9 10 etMsg = (EditText)findViewById(R.id.editText1); 11 sendButton = (Button)findViewById(R.id.button1); 12 13 // 获取共享属性操作的工具(文件名,操作模式) 14 sp = This.getSharedPreferences("data", 0); 15
上方第14行代码中,调用的方法是:public SharedPreferences getSharedPreferences (String name, int mode)
其中,第一个参数代表XML文件(不要加后缀名),如果有这个文件,就会操作这个文件,如果没有这个文件,就会创建这个文件;第二个参数代表一种操作模式,0代表私有。
然后,我们要在onPause()方法里保存数据,之所以在onPause()方法里保存,是因为在所有可能会被内存销毁的生命周期函数中,而onPause()方法最先执行。代码如下:
//在onPause()方法中保存数据 @Override protected void onPause() super.onPause(); String msg = etMsg.getText().toString(); Editor editor = sp.edit(); editor.putString("msg", msg); //执行方法:public abstract SharedPreferences.Editor putString (String key, String value) editor.commit();
将数据保存在msg变量中,然后拿到Editor这个编辑器,给它put进去。当然,这些只是在内存中操作,如果要反映到文件当中,还要执行commit()方法。
(2)还原数据:
紧接着,我们要在onResume()方法中重新还原数据:(为什么要在这个方法中还原数据,不用我多解释)
@Override protected void onResume() super.onResume(); etMsg.setText(sp.getString("msg", ""));
当程序中第一次启动的时候,并没有保存数据,所以返回一个默认的空值。将这个返回的数据放到etMsg控件中就行了。
现在我们运行程序,是可以执行的。
例如,现在编辑内容,然后去别的程序,再回来的时候(就算我们把程序退出了),编辑的内容还依然存在。这个时候,我们打开文件浏览器,发现数据是保存在/data/data/<packagename>/shared_prefs/目录的data.xml文件当中的,而且是永久保存;所以,当在onResume()方法还原数据之后,我们还要加一部分代码,来删掉这个文件里的内容(无法删除文件本身),不然就会永久保存本地成为垃圾了。代码如下:
protected void onResume() super.onResume(); etMsg.setText(sp.getString("msg", "")); Editor editor = sp.edit(); editor.clear(); editor.commit();
总结之后,最终的完整版代码如下:
activity_main.xml文件代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <EditText android:id="@+id/editText1" android:layout_width="match_parent" android:layout_height="0dp" android:gravity="top" android:layout_weight="1" android:ems="10" /> <Button android:id="@+id/button1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button" /> </LinearLayout>
MainActivity.java的代码如下:
1 package com.example.smyh001; 2 import android.app.Activity; 3 import android.content.SharedPreferences; 4 import android.content.SharedPreferences.Editor; 5 import android.os.Bundle; 6 import android.view.Menu; 7 import android.widget.Button; 8 import android.widget.EditText; 9 public class MainActivity extends Activity 10 private EditText etMsg ; 11 private Button sendButton; 12 private SharedPreferences sp; 13 14 @Override 15 protected void onCreate(Bundle savedInstanceState) 16 super.onCreate(savedInstanceState); 17 setContentView(R.layout.activity_main); 18 19 etMsg = (EditText)findViewById(R.id.editText1); 20 sendButton = (Button)findViewById(R.id.button1); 21 22 // 获取共享属性操作的工具 23 sp = getSharedPreferences("data", 0); 24 25 //在onPause()方法中保存数据 26 @Override 27 protected void onPause() 28 super.onPause(); 29 String msg = etMsg.getText().toString(); 30 Editor editor = sp.edit(); 31 editor.putString("msg", msg);//执行方法:public abstract SharedPreferences.Editor putString (String key, String value) 32 editor.commit(); 33 34 35 //在onResume()方法中还原数据 36 @Override 37 protected void onResume() 38 super.onResume(); 39 etMsg.setText(sp.getString("msg", "")); 40 Editor editor = sp.edit(); 41 editor.clear(); 42 editor.commit(); 43 44
运行程序之后,我们在编辑框输入一些文字:
退出程序,然后导出data.xml文件,打开后显示如下:
说明输入的文本被保存在了data.xml文件当中。当我们再回到程序,之前输入的文字会被保留在界面上,而data.xml文件中的文本则会被清空。
代码优化:
上方代码中如果我们在第40行代码的后面加下面这一行代码:
etMsg.setSelection((sp.getString("msg", "")).length());
当返回到原程序时,setSelection方法可将输入光标移动到文本的末尾位置以便继续输入。里面的参数sp.getString("msg", "")是之前所输入的字符串。
四、实例:实现记住密码的功能
暂略。
五、PreferenceActivity类的使用:
后面的章节会讲到。
以上是关于HTML5的5种存储方式详解的主要内容,如果未能解决你的问题,请参考以下文章