众所周知,对于一个应用程序来说,不管是web工程还是app工程,对数据的存储往往分为两大块,一块是存储在大容量的数据库中,例如流行的mySQL数据库,Oracle数据库等,存储在数据库的信息一般都是存储到服务器主机的硬盘当中。而除此之外,还有一种将数据临时存储在客户端如浏览器的方式,本文章所讲的主要内容就是这第二种方式,主要讲述各存储方法的区别点和共同点。 在说数据存储之前,不得不先提到一个作为开发者耳熟能详的东西:跨域问题。
首先,介绍下什么是跨域,为什么会跨域。
(一)什么是跨域?为什么会有跨域问题?
说到跨域首先要介绍跨域的产生原因:浏览器的同源策略。
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。说简单点,同源策略就是浏览器本身的一种特殊属性,浏览器在访问资源时会在同源策略约束下,避免不同的站点相互之间轻易的获取信息。
举个例子:用户在A网站登录用户,在网站上存储了用户的个人信息,cookies等等,这时候用户用同一个浏览器新建了一个标签页打开了B网站,而B网站上做了一个操作是获取当前登录用户的用户信息以及cookies等,并利用A网站里的接口发送请求。
用户在A站点登录之后,又打开了B站点,但是用户没有进行其他操作,而在B站点中,站点B获取了用户的数据,并且调用A站点中的方法,自动做相关操作,如进行转账,此时,若系统不进行区别请求是从哪里发来的,只要请求被访问,就做相应操作,那么很轻松的B站点就对用户U的账户进行了转账操作,而用户不知情。
浏览器本身做了同源的校验,只要不符合浏览器的同源规则,那么默认不是同源站点,不同源的站点之间不能轻易进行相互获取资源,除非某一站点进行了授权,方可使本不同源的站点资源。
所谓同源是指,协议,域名,端口相同。当一个浏览器的两个tab页中分别打开百度和谷歌的页面。浏览器的百度tab页执行脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。 如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
我们知道,浏览器是以HTTP请求模式获取请求资源,如:Http://www.baidu.com:8080/xxxx。其中HTTP是请求协议,www.baidu.com是域名,8080是端口号,请求的意思是 使用HTTP协议模式,从域名为www.baidu.com的服务器上8080端口部署的服务下请求资源XXXX。
那么当协议,域名,端口不相同时,即为不同源。
现在有一个网站:http://www.a.com/a。
https://www.a.com/a :不同源,协议不同,此处协议是https!
http://www.b.com/a :不同源,域名不同
http://www.a.com:8080/a :不同源,端口不同
http://www.a.com/b :同源
综上,跨域就是请求路径的url不同源。
可参考文档:https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy
(二):session,localStorage,sessionStorage,cookies存储
1:存储机制的区别:
localStorage、sessionStorage、cookies都可以用来在浏览器进行数据的缓存存储。sessionStorage、cookies这两个存储随着关闭浏览器或者停止对服务器的访问而会消失,并不会永久的存在。
localStorage是通过浏览器存储到本机机器上的磁盘中,生成.localstorage文件但其实是sqlit数据库文件。这种不会通过关闭浏览器清除,只有当用户手动清除浏览器缓存才能真正的清除掉数据。
session不是用来存储在客户端,而是存储在整个会话当中(即浏览器访问服务器这个过程,关闭浏览器或停止服务器即断开会话),浏览器关闭,session即清除。
localStorage - 没有时间限制的数据存储 sessionStorage - 针对一个 session 的数据存储。
在以前,这些缓存存储都是由 cookies 完成的。但是cookies不适合大数据量的存储,它们由每个对服务器的请求来传递,这使得 cookie 速度很慢而且效率也不高。
在 HTML5 中,数据不是由每个服务器请求传递的,而是只有在请求时使用数据。它使在不影响网站性能的情况下存储大量数据成为可能。对于不同的网站,数据存储于不同的区域,并且一个网站只能访问其自身的数据。
即当浏览器打开的tab满足同源策略后,可以在各页面之间进行数据的相互存取操作,这样就可以不用反复进行重复的数据请求操作,如登录权限,获取用户信息等等。
2:存储操作 (参考 W3SCHOOL)
进行数据的存储操作使用localStorage.setItem(key,value),取数据使用localStorage.getItem(key)
if (typeof(Storage) !== "undefined") {//判断浏览器是否支持
localStorage.setItem("lastname", "1111");
localStorage.getItem("lastname");
} else {
document.getElementById("result").innerHTML = "抱歉!您的浏览器不支持 Web Storage ...";
}
sessionStorage进行数据的存储操作使用sessionStorage.setItem(key,value),
取数据使用sessionStorage.getItem(key)
Web Storage的概念和cookie相似,区别是它是为了更大容量存储设计的。Cookie的大小是受限的,并且每次你请求一个新的页面的时候Cookie都会被发送过去,这样无形中浪费了带宽,另外cookie还需要指定作用域,不可以跨域调用。
除此之外,Web Storage拥有setItem,getItem,removeItem,clear等方法,不像cookie需要前端开发者自己封装setCookie,getCookie。但是Cookie也是不可以或缺的:Cookie的作用是与服务器进行交互,作为HTTP规范的一部分而存在 ,而Web Storage仅仅是为了在本地“存储”数据而生。
removeItem删除key,如sessionStorage.removeItem(key)。
.clear清除所有:sessionStorage.clear();
使用本地存储之前一定要先进行浏览器是否支持校验,防止浏览器版本过低导致数据不能进行正确的存储。
if (typeof(Storage) !== "undefined") {
// 针对 localStorage/sessionStorage 的代码
} else {
// 抱歉!不支持 Web Storage ..
}
(三)跨域的解决方式