最近央视播出了中国诗词大赛,看到了一首诗,送给大家

《春宵·春宵一刻值千金》

作者:苏轼 【宋代】

春宵一刻值千金,花有清香月有阴。

歌管楼台声细细,秋千院落夜沉沉。

好了,言归正传,今天在项目中为了性能问题,打算用本地存储来保存网页的状态,h5中推出两个非常强大的API---sessionStorage和localStorage,经实际检测发现可以兼容到IE8,但是IE还有自己的本地存储方案--UserDataStorage,可以兼容到IE5。可能有人会问,为什么不用cookie,前面说到了性能的问题,cookie的作用域在指定的路径以及它的子路径都有效,并且会附加到请求中,这会发送很多不必要的数据。

于是写了以下兼容所有浏览器的代码,那么问题来了,先遇到了IE不能识别自己的load()方法,然后又遇到了手机浏览器的问题,下面将会细说。

  1. var storageObj = window.sessionStorage || ( window.UserDataStorage && new UserDataStorage() )|| new cookieStorage();

其中cookieStorage.js文件如下,cookie没有对应的API,为了和sessionStorage对象使用相同的方法,需要进行封装。

  1. function cookieStorage( path, maxage ){
  2.  
  3. var cookie = ( function(){
  4.  
  5. var cookie = {};
  6. var all = document.cookie;
  7.  
  8. if ( all === '' ) {
  9.  
  10. return cookie;
  11.  
  12. }
  13.  
  14. var list = all.split( '; ' );
  15. for( var i = 0; i < list.length; i++ ){
  16.  
  17. var tmp = list[i];
  18. var p = tmp.indexOf( '=' );
  19. var name = tmp.substring( 0, p );
  20. var value = tmp.substring( p + 1 );
  21. value = decodeURIComponent( value );
  22. cookie[name] = value;
  23.  
  24. }
  25.  
  26. return cookie;
  27.  
  28. }() );
  29.  
  30. var keys = [];
  31. for( var key in cookie ){
  32.  
  33. keys.push( key );
  34.  
  35. }
  36.  
  37. this.length = keys.length;
  38.  
  39. this.key = function( n ){
  40.  
  41. if( n < 0 || n >= keys.length ){
  42.  
  43. return null;
  44.  
  45. }
  46.  
  47. return keys[n];
  48.  
  49. };
  50.  
  51. this.getItem = function( name ){
  52.  
  53. return cookie[name] || null;
  54.  
  55. };
  56.  
  57. this.setItem = function( key, value ){
  58.  
  59. if ( !( key in cookie ) ) {
  60.  
  61. keys.push( key );
  62. this.length++;
  63. }
  64.  
  65. cookie[key] = value;
  66.  
  67. var tmp = key + '=' + encodeURIComponent( value );
  68. if ( maxage ) {
  69.  
  70. tmp += '; max-age=' + maxage;
  71.  
  72. }
  73. if ( path ) {
  74.  
  75. tmp += '; path=' + path;
  76.  
  77. }
  78.  
  79. document.cookie = tmp;
  80.  
  81. };
  82.  
  83. this.removeItem = function( key ){
  84.  
  85. if ( !( key in cookie ) ) {
  86.  
  87. return ;
  88.  
  89. }
  90.  
  91. delete cookie[key];
  92.  
  93. for( var i = 0; i < keys.length; i++ ){
  94.  
  95. if ( keys[i] === key ) {
  96.  
  97. keys.splice( i, 1 );
  98. break;
  99.  
  100. }
  101. }
  102.  
  103. this.length--;
  104. document.cookie = key + '=; max-age=0';
  105.  
  106. };
  107.  
  108. this.clear = function(){
  109.  
  110. for( var i = 0; i < keys.length; i++ ){
  111.  
  112. document.cookie = keys[i] + '=; max-age=0';
  113.  
  114. }
  115.  
  116. cookie = {};
  117. keys = [];
  118. this.length = 0;
  119.  
  120. };
  121.  
  122. }

注意:document.cookie = tmp相当于add函数,并不是重置cookie

其中userDataStorage.js,同cookie一样也需要封装,具体的使用方法请查看IE文档,先贴代码如下:

  1. function UserDataStorage( maxage ){
  2.  
  3. var memory = document.createElement( 'div' );
  4. memory.style.display = 'none';
  5. memory.style.behavior = 'url("#default#userData")';
  6. document.body.appendChild( memory );
  7.  
  8. if ( maxage ) {
  9.  
  10. var now = new Date().getTime();
  11. var expires = now + maxage * 1000 ;
  12. memory.expires = new Date( expires ).toUTCString();
  13.  
  14. }
  15.  
  16. memory.load( 'MyDataStorage' );
  17.  
  18. this.getItem = function( key ){
  19.  
  20. return memory.getAttribute( key ) || null;
  21. };
  22.  
  23. this.setItem = function( key, value ){
  24.  
  25. memory.setAttribute( key, value );
  26. memory.save( 'MyDataStorage' );
  27.  
  28. };
  29.  
  30. this.removeItem = function( key ){
  31.  
  32. memory.removeAttribute( key );
  33. memory.save( 'MyDataStorage' );
  34. };
  35.  
  36. }

问题来了

第一,userDataStroage仅适用于IE,所以为了性能加入以下代码

  1. <!--[if IE]>
  2. <script src="/userDataStorage.js"></script>
  3. <![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了,新值只会覆盖旧值。

  1. var Storage = window.sessionStorage || new cookieStorage( '/cgi-bin/luci/' );

你以为这就搞定了吧,问题又出现了,在手机360浏览器,经检测是支持sessionStorage的,但是发现当设了sessionStorage后,跳转页面,sessionStorage作用域变了,获取不到原来设的那个sessionStorage的值了,值为null,郁闷,但是在其他手机浏览器是好的,还有就是在手机浏览器无痕模式下,也会失效,最后为了兼容只能采用cookie的方案了,如果你的项目要求兼容的浏览器不那么严格的话,可以尝试以上方案。至于无痕模式的解决方案还在探索中,以后会发出来。

总结,做个前端真不容易啊!一堆堆的坑等着你跳。

sessionStorage,UserDataStorage,cookie全兼容写法存在的问题的更多相关文章

  1. sessionStorage & localStorage & cookie

    sessionStorage & localStorage & cookie 概念 html5中的Web Storage包括了两种存储方式:sessionStorage和localSt ...

  2. localStorage sessionStorage 和cookie等前端存储方式总结

    localStorage sessionStorage 和cookie localStorage localStorage是本地存储的,除非清空本地数据 localStorage不会自动把数据发给服务 ...

  3. 前端 JS,localStorage/sessionStorage、cookie 及 url 等实现前台数据共享、传输

    需求是这样的:需要统计用户公司某款产品用户的回馈情况,美工给的设计多个psd,每个页面里面都有一个选择题,让用户选择自己的答案,最后经过几次选择之后在最后一个页面统一提交到后台!所以这里引出的技术需求 ...

  4. localStorage、sessionStorage和cookie的区别

    本地客户端(浏览器)查看三者信息: HTML4的本地存储:cookie 浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式,可以利用cookie,session等根服务端进行数据交互. 一.co ...

  5. 浅谈localStorage的使用场景和优劣势,以及sessionStorage和cookie

    一.localStorage,sessionStorage,cookie的简单介绍 localStorage:仅在客户端存储不参与服务器通信,存储大小一般为5M,如果不是人为清除,那么即使是关闭浏览器 ...

  6. localStrorage、 sessionStorage 、cookie

          HTML5中增加了两种全新数据存储方式:Web Storage和Web SQL Database. 前者可用于临时或永久保存客户端的少量数据:后者是客户端本地化的一套数据库系统,可将大量数 ...

  7. localStorage , sessionStorage ,cookie 使用介绍

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. localStorage,sessionStorage和cookie的区别

    sessionStorage 和 localStorage 是HTML5 Web Storage API 提供的,可以方便的在web请求之间保存数据.有了本地数据,就可以避免数据在浏览器和服务器间不必 ...

  9. js使用sessionStorage、cookie保存token

    本文是参考别人的博客写的,图片直接用的别人的 1.Token:token是客户端频繁向服务器端请求数据,服务器频繁的去数据库查询用户名和密码进行对比,判断用户名和密码正确与否,并作出相应的提示,在这样 ...

随机推荐

  1. Springboot与Mybatis整合

    最近自己用springboot和mybatis做了整合,记录一下: 1.先导入用到的jar包 <dependency> <groupId>org.springframework ...

  2. AngularJS中的DOM与事件

      前 言 AngularJS中的DOM与事件   AngularJS 为 HTML DOM 元素的属性提供了绑定应用数据的指令.  ng-disabled="true/false" ...

  3. Mybatis逆向生成Mapper文件

    本文参考博客 http://blog.csdn.net/for_my_life/article/details/51228098 1. 在resources根目录下添加generator.proper ...

  4. 开始使用ASP.NET Core - 创建第一个Web应用

    .NET Core 是.NET Framework的新一代跨平台应用程序开发框架,是微软在一开始发展时就开源的软件平台,由于 .NET Core 的开发目标是跨平台的 .NET 平台,因此 .NET ...

  5. React的组件用法

    React.createClass() 中文翻译 https://discountry.github.io/react/3.4K ( https://doc.react-china.org868 ) ...

  6. 动易CMS - 设为首页代码和加入收藏代码(兼容各种浏览器)

    注意: 这里虽然说是兼容,但是有些浏览器的设置就是不支持用js来把页面设为首页,加入收藏夹,只能让用户手动去在浏览器或者按键去设置这些功能,这里说的兼容是指当浏览器有这个设置的时候js会有提示.   ...

  7. Go语言下载、安装、配置、使用

    Go语言 Go语言(Golang,The Go Programming Language),是谷歌2009发布的第二款开源编程语言.2009年7月份,谷歌曾发布了Simple语言,它是用来开发Andr ...

  8. 用matlab给图像加高斯噪声和椒盐噪声(不调用imnoise函数)

    图像画面中的噪声,大致可以分为两类:高斯噪声和椒盐噪声.在这里,我们先看下图像中两种噪声各自的特征. 椒盐噪声:噪声幅值基本相同,但出现位置随机. 高斯噪声:图像中每一点都存在噪声,但幅值是随机分布的 ...

  9. C# JAVA成员访问修饰符比较

    在面向对象的访问修饰符中常用的有public ,private ,protected C# 访问修饰符: private < protected internal < internal/p ...

  10. Docker到底是什么

    简单讲docker和vm虚拟机类似,都是在同一硬件上虚拟化出多个服务器应用实例的功能,据Bottomley声称,借助经过全面调优的容器系统,你就可以在同一硬件上拥有数量比使用Xen虚拟机或KVM虚拟机 ...