sessionStorage,UserDataStorage,cookie全兼容写法存在的问题
最近央视播出了中国诗词大赛,看到了一首诗,送给大家
《春宵·春宵一刻值千金》
作者:苏轼 【宋代】
春宵一刻值千金,花有清香月有阴。
歌管楼台声细细,秋千院落夜沉沉。
好了,言归正传,今天在项目中为了性能问题,打算用本地存储来保存网页的状态,h5中推出两个非常强大的API---sessionStorage和localStorage,经实际检测发现可以兼容到IE8,但是IE还有自己的本地存储方案--UserDataStorage,可以兼容到IE5。可能有人会问,为什么不用cookie,前面说到了性能的问题,cookie的作用域在指定的路径以及它的子路径都有效,并且会附加到请求中,这会发送很多不必要的数据。
于是写了以下兼容所有浏览器的代码,那么问题来了,先遇到了IE不能识别自己的load()方法,然后又遇到了手机浏览器的问题,下面将会细说。
var storageObj = window.sessionStorage || ( window.UserDataStorage && new UserDataStorage() )|| new cookieStorage();
其中cookieStorage.js文件如下,cookie没有对应的API,为了和sessionStorage对象使用相同的方法,需要进行封装。
function cookieStorage( path, maxage ){
var cookie = ( function(){
var cookie = {};
var all = document.cookie;
if ( all === '' ) {
return cookie;
}
var list = all.split( '; ' );
for( var i = 0; i < list.length; i++ ){
var tmp = list[i];
var p = tmp.indexOf( '=' );
var name = tmp.substring( 0, p );
var value = tmp.substring( p + 1 );
value = decodeURIComponent( value );
cookie[name] = value;
}
return cookie;
}() );
var keys = [];
for( var key in cookie ){
keys.push( key );
}
this.length = keys.length;
this.key = function( n ){
if( n < 0 || n >= keys.length ){
return null;
}
return keys[n];
};
this.getItem = function( name ){
return cookie[name] || null;
};
this.setItem = function( key, value ){
if ( !( key in cookie ) ) {
keys.push( key );
this.length++;
}
cookie[key] = value;
var tmp = key + '=' + encodeURIComponent( value );
if ( maxage ) {
tmp += '; max-age=' + maxage;
}
if ( path ) {
tmp += '; path=' + path;
}
document.cookie = tmp;
};
this.removeItem = function( key ){
if ( !( key in cookie ) ) {
return ;
}
delete cookie[key];
for( var i = 0; i < keys.length; i++ ){
if ( keys[i] === key ) {
keys.splice( i, 1 );
break;
}
}
this.length--;
document.cookie = key + '=; max-age=0';
};
this.clear = function(){
for( var i = 0; i < keys.length; i++ ){
document.cookie = keys[i] + '=; max-age=0';
}
cookie = {};
keys = [];
this.length = 0;
};
}
注意:document.cookie = tmp相当于add函数,并不是重置cookie
其中userDataStorage.js,同cookie一样也需要封装,具体的使用方法请查看IE文档,先贴代码如下:
function UserDataStorage( maxage ){
var memory = document.createElement( 'div' );
memory.style.display = 'none';
memory.style.behavior = 'url("#default#userData")';
document.body.appendChild( memory );
if ( maxage ) {
var now = new Date().getTime();
var expires = now + maxage * 1000 ;
memory.expires = new Date( expires ).toUTCString();
}
memory.load( 'MyDataStorage' );
this.getItem = function( key ){
return memory.getAttribute( key ) || null;
};
this.setItem = function( key, value ){
memory.setAttribute( key, value );
memory.save( 'MyDataStorage' );
};
this.removeItem = function( key ){
memory.removeAttribute( key );
memory.save( 'MyDataStorage' );
};
}
问题来了
第一,userDataStroage仅适用于IE,所以为了性能加入以下代码
<!--[if IE]>
<script src="/userDataStorage.js"></script>
<![endif]-->
经浏览器查看,这句代码在IE10和IE11中起到了反作用,就像其他浏览器一样,userDataStorage.js被过滤了
,晕,这不是IE才执行的代码? IE10和IE11不是IE?????
但是IE9及以下能够加载,在网上查了一下可以添加<meta http-equiv="X-UA-Compatible"
content="IE=9">指定IE9模式来解析。但是这样就不能用IE10的新特性了。
其次,IE的UserDataStorage需要用到.load()来加载数据,但是亲测在IE8和IE9中不能识别这个函数,打断点发现新建的标签根本没有这个方法。
我的天啊,这是神马鬼。
然后老老实实的用cookie来做不兼容sessionStorage的备选方案,但在使用的时候发现出现两个同名但不同值的cookie(如下图),我和我的小伙伴都惊呆了
,后来才发现,是没有设置路径,cookie默认是用当前文档的路径来做路径的,默认失效时间是session时间,路径不同则cookie也不同,即使名称一样。在不指定路径的情况下,两个不同路径的文件设同名的cookie就会出现以上情况,具体的路径的设置和时间设置以及作用域就不多说了,可参考其他文档。
顺便说下在google中查看cookie的两种方法
1、在浏览器的地址栏头部点击那个感叹号,可以查看到详细的路径信息
2、在控制台看,路径信息被遮挡了,只能看到部分
于是我设置了统一的路径,这样就不会出现同名的cookie了,新值只会覆盖旧值。
var Storage = window.sessionStorage || new cookieStorage( '/cgi-bin/luci/' );
你以为这就搞定了吧,问题又出现了
,在手机360浏览器,经检测是支持sessionStorage的,但是发现当设了sessionStorage后,跳转页面,sessionStorage作用域变了,获取不到原来设的那个sessionStorage的值了,值为null,郁闷,但是在其他手机浏览器是好的,还有就是在手机浏览器无痕模式下,也会失效,最后为了兼容只能采用cookie的方案了,如果你的项目要求兼容的浏览器不那么严格的话,可以尝试以上方案。至于无痕模式的解决方案还在探索中,以后会发出来。
总结,做个前端真不容易啊!一堆堆的坑等着你跳。
sessionStorage,UserDataStorage,cookie全兼容写法存在的问题的更多相关文章
- sessionStorage & localStorage & cookie
sessionStorage & localStorage & cookie 概念 html5中的Web Storage包括了两种存储方式:sessionStorage和localSt ...
- localStorage sessionStorage 和cookie等前端存储方式总结
localStorage sessionStorage 和cookie localStorage localStorage是本地存储的,除非清空本地数据 localStorage不会自动把数据发给服务 ...
- 前端 JS,localStorage/sessionStorage、cookie 及 url 等实现前台数据共享、传输
需求是这样的:需要统计用户公司某款产品用户的回馈情况,美工给的设计多个psd,每个页面里面都有一个选择题,让用户选择自己的答案,最后经过几次选择之后在最后一个页面统一提交到后台!所以这里引出的技术需求 ...
- localStorage、sessionStorage和cookie的区别
本地客户端(浏览器)查看三者信息: HTML4的本地存储:cookie 浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式,可以利用cookie,session等根服务端进行数据交互. 一.co ...
- 浅谈localStorage的使用场景和优劣势,以及sessionStorage和cookie
一.localStorage,sessionStorage,cookie的简单介绍 localStorage:仅在客户端存储不参与服务器通信,存储大小一般为5M,如果不是人为清除,那么即使是关闭浏览器 ...
- localStrorage、 sessionStorage 、cookie
HTML5中增加了两种全新数据存储方式:Web Storage和Web SQL Database. 前者可用于临时或永久保存客户端的少量数据:后者是客户端本地化的一套数据库系统,可将大量数 ...
- localStorage , sessionStorage ,cookie 使用介绍
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- localStorage,sessionStorage和cookie的区别
sessionStorage 和 localStorage 是HTML5 Web Storage API 提供的,可以方便的在web请求之间保存数据.有了本地数据,就可以避免数据在浏览器和服务器间不必 ...
- js使用sessionStorage、cookie保存token
本文是参考别人的博客写的,图片直接用的别人的 1.Token:token是客户端频繁向服务器端请求数据,服务器频繁的去数据库查询用户名和密码进行对比,判断用户名和密码正确与否,并作出相应的提示,在这样 ...
随机推荐
- C# 下搭建最新版OpenCV(Emgu CV)开发环境
既然是"最新版" 首先当然是去sf找安装包: https://sourceforge.net/projects/emgucv/files/emgucv/ 或着去github主页上c ...
- getOutputStream() has already been called for this response
错误日志里偶尔会有getOutputStream() has already been called for this response这个错误 最近发现了高概率复现条件,所以顺手解决了一下: 首先根 ...
- Linux Ubuntu从零开始部署web环境及项目 -----部署项目 (三)
上一篇讲了如何在linux搭建web环境,这边将如何部署项目. 1,打包项目包 2,上传项目包 将.war项目包通过xftp上传到tomcat目录wabapps目录下 3,启动项目 通过xshell命 ...
- FastDFS安装步骤
FastDFS是用c语言编写的一款开源的分布式文件系统,充分考虑了冗余备份.负载均衡.线性扩容等机制,并注重高可用.高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传.下 ...
- Java数据结构和算法总结-数组、二分查找
前言:在平时开发中数组几乎是最基本也是最常用的数据类型,相比链表.二叉树等又简单很多,所以在学习数据和算法时用数组来作为一个起点再合适不过了.本篇博文的所有代码已上传 github ,对应工程的 ar ...
- 深入浅出AQS之条件队列
相比于独占锁跟共享锁,AbstractQueuedSynchronizer中的条件队列可能被关注的并不是很多,但它在阻塞队列的实现里起着至关重要的作用,同时如果想全面了解AQS,条件队列也是必须要学习 ...
- Paint the Grid Reloaded ZOJ - 3781 图论变形
Paint the Grid Reloaded Time Limit: 2000MS Memory Limit: 65536KB 64bit IO Format: %lld & %ll ...
- php正则匹配utf-8编码的中文汉字
在javascript中,要判断字符串是中文是很简单的.比如: var str = "php编程"; if (/^[\u4e00-\u9fa5]+$/.test(str)) { a ...
- java中继承和组合的区别
子类继承父类,父类的所有属性和方法都可以被子类访问和调用.组合是指将已存在的类型作为一个新建类的成员变量类型,又叫"对象持有". 通过组合和继承,都可以实现系统功能的重用和代码的复 ...
- 从零开始配置TypeScript + React + React-Router + Redux + Webpack开发环境
转载请注明出处! 说在前面的话: 1.为什么不使用现成的脚手架?脚手架配置的东西太多太重了,一股脑全塞给你,我只想先用一些我能懂的库和插件,然后慢慢的添加其他的.而且自己从零开始配置也能学到更多的东西 ...