为什么IE8以上不支持html5 localstoragee

IE6/7的localStorage兼容解决方案 - 推酷
IE6/7的localStorage兼容解决方案
本地储存在现代Web框架中起着重要的作用,但最简单的标准本地储存 localStorage 也是从IE8才开始支持的。那么在IE6/7上要怎么办?IE原本也有自己的本地储存接口 userData ,通过这个接口我们可以照着标准 localStorage 来重新封装,以便和标准浏览器统一。
同VML一样, userData 也是为元素添加一个Behavior后让元素支持相关方法。最基本的两个方法是 save 和 load ,他们可以保存和加载元素上的属性(attributes)。
&!--请在IE6/7上测试--&&script id=&test&&test.addBehavior(&#default#userData&);test.setAttribute(&data-data&,&测试数据&);test.save(&my test data&);test.setAttribute(&data-data&,&&);test.load(&my test data&);document.write(test.getAttribute(&data-data&));&/script& 看完上面代码大概就能知道 userData 的逻辑了吧?
下面我把它封装好,以便与标准保持一致:
重启浏览器后再测试
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致为什么IE8以上不支持localStorage_百度知道
为什么IE8以上不支持localStorage
2;&}else{alert(&quot,再开启页面查看;script&gt,那么笔者将刚刚的测试页面部署到TomCat服务器;body&gt.localStorage){alert(&quot!DOCTYPE HTML&head&&#47.js&script src=&quot.7;javascript&text&#47,出现了下面的问题;; &lt,存储的数据没有时间限制;jquery-1;&gt:&}} &但是通过html5test网站查询;t support localStorage for local files即IE9 localStorage不支持本地文件;&lt:IE9 doesn&#39,通过查阅官方资料了解到localStorage ,但是笔者今天做了个小demo测试;&#47. &html&html&head& &&gt.onload=function(){if(body&gt:代码;&#47。按照官网说法IE8及以上的版本均支持localS &);Test LocalStorage &not support&script&/ &script type=&/&);support&quot:是html5提供的客户端存储数据的方法,发现当前使用的IE9版本是支持localStorage的那么问题出在什么地方呢
自动化开发工程师
其他类似问题
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁您所在的位置: &
HTML 5本地存储之兼容性与存储监听
HTML 5本地存储之兼容性与存储监听
HTML5China
onstorage可用时,监听事件并在事件触发时判断是否指定的key,onstorage不可用(IE8以下、Chrome因domain问题)时使用Timer来检查。
很早之前调研过HTML5的-,大致上对localStorage、sessionStorage等API做了下了解,但是一直没有机会真正的在项目中使用。终于这次借重构Web IM的机会,对本地存储做了更深入的使用,除了基本的API使用之外还在次基础上封装了一些应用层的库,例如Tab之间的操作同步、Tab之间的请求同步等。本文主要做一个阶段性的经验总结。
一、localStorge onstorage事件的兼容性
1. 触发情况
IE8/IE9/Firefox3.6: 在页面A中注册onstorage事件,修改localStorage时,A页面和其他页面都能收到onstorage事件。因此,对于这些监听onstorage时需要自己判断是否是本页面触发的,并且忽略本页面触发的行为。
Chrome12/Firefox4/Opera11/Safari5中只有收到由其他页面触发的onstorage事件。
此外,Chrome14 DEV版本中测试发现,在页面设置了document.domain之后,onstorage事件无论如何都不会触发,此Bug导致在Chrome下无法使用onstorage事件。
2. 事件注册
IE需要注册在document上,其他均注册在window上。
&if(&document.attachEvent&&&&!K.Browser.opera&)&{&&&&& &&&&&document.attachEvent(&onstorage&,&_onstorage(key,callback));&&&&& &}&&&&& &&else{&&&&& &&&&&window.addEventListener(&storage&,&_onstorage(key,callback),&false);&&&&& &};&&&&& &
3. 事件对象
IE中的storageEvent对象不包含key/newValue/oldValue等属性,因此如果想知道是哪个Key的数据发生了变化需要自己处理,其他浏览器则可以直接获得数据。
4. 数据的获取
IE9下在事件触发时尽然无法立即获取到对应key的值,需要使用setTimeout做异步处理。其他浏览器状况良好。
二、监听某个Key的变化
监听某个key也就是在onstorage的基础上更精细一些,这是之后各种应用的基础。以下为实现方案:
1. onstorage可用时,监听事件并在事件触发时判断是否指定的key
2. onstorage不可用(IE8以下、Chrome因domain问题)时使用Timer来检查
JavaScript Code复制内容到剪贴板
var&LocalStorage&=&(function(){&&&&& &&&&&&&&&var&ls&=&window.localS&&&&& &&&&&& &&&&&&&&&function&_onstorage(&key,&callback&){&&&&& &&&&&&&&&&&&&var&oldValue&=&ls[key];&&&&& &&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&return&function(&e&){&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&setTimeout(&function(){&&&&& &&&&&&&&&&&&&e&=&e&||&window.storageE&&&&& &&&&&& &&&&&&&&&&&&&var&tKey&=&e.key,&&&&& &&&&&&&&&&&&&&&&&newValue&=&e.newV&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&if(&!tKey&){&&&&& &&&&&&&&&&&&&&&&&var&nv&=&ls[key];&&&&& &&&&&&&&&&&&&&&&&if(&nv&!=&oldValue&){&&&&& &&&&&&&&&&&&&&&&&&&&&tKey&=&&&&&& &&&&&&&&&&&&&&&&&&&&&newValue&=&&&&&& &&&&&&&&&&&&&&&&&}&&&&& &&&&&& &&&&&&&&&&&&&}&&&&& &&&&&& &&&&&&&&&&&&&if(&tKey&==&key&){&&&&& &&&&&&&&&&&&&&&&&callback&&&&callback(newValue);&&&&& &&&&&& &&&&&&&&&&&&&&&&&oldValue&=&newV&&&&& &&&&&&&&&&&&&}&&&&& &&&&&&&&&},&0&);&&&&& &&&&&&&&&&&&&}&&&&& &&&&&&&&&}&&&&& &&&&&return&{&&&&& &&&&&&&&&getItem:&function(&key&){&&&&& &&&&&&&&&&&&&return&ls.getItem(&key&);&&&&& &&&&&&&&&},&&&&& &&&&&&&&&setItem:&function(&key,&val&){&&&&& &&&&&&&&&&&&&return&ls.setItem(&key,&val&);&&&&& &&&&&&&&&},&&&&& &&&&&&&&&removeItem:&function(&key,&val&){&&&&& &&&&&&&&&&&&&return&ls.removeItem(&key&);&&&&& &&&&&&&&&},&&&&& &&&&&&&&&clear:&function(){&&&&& &&&&&&&&&&&&&return&ls.clear();&&&&& &&&&&&&&&},&&&&& &&&&&&&&&onstorage:&function(&key,&callback&){&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&var&b&=&K.B&&&&& &&&&&& &&&&&&&&&&&&&if(&!this.useTimer&){&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if(&document.attachEvent&&&&!K.Browser.opera&)&{&&&&& &&&&&&&&&&&&&&&&&&&&&document.attachEvent(&onstorage&,&_onstorage(key,callback));&&&&& &&&&&&&&&&&&&&&&&}&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&else{&&&&& &&&&&&&&&&&&&&&&&&&&&window.addEventListener(&storage&,&_onstorage(key,callback),&false);&&&&& &&&&&&&&&&&&&&&&&};&&&&& &&&&&&&&&&&&&}&&&&& &&&&&&&&&&&&&else{&&&&& &&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&var&listener&=&_onstorage(&key,&callback&);&&&&& &&&&&&&&&&&&&&&&&setInterval(function(){&&&&& &&&&&&&&&&&&&&&&&&&&&listener({});&&&&& &&&&&&&&&&&&&&&&&},&this.interval);&&&&& &&&&&&&&&&&&&}&&&&& &&&&&&&&&},&&&&& &&&&&&&&&&&&&&&&&&useTimer:&(&K.Browser.ie&&&&K.Browser.ie&&&8&)&||&(&K.Browser.chrome&),&&&&& &&&&&&&&&&&&&&&&&&interval:&1000&&&&& &&&&&};&&&&& &})();&&&&& &
以上是LocalStorage接口的完整封装,在localStorage不可用时使用UserData等其他替代方案来实现以上的接口即可。
【编辑推荐】
【责任编辑: TEL:(010)】
关于的更多文章
本书的重点是使用HTML5、CSS3 及JavaScript 等Web 标准来为iOS
所以姑娘,让我们做一枚花见花开的程序媛。
又到了一周的末尾,闷热过后,这周的温度算是降下来了
掌握一门技术,首要的是掌握其基础。笔者从事.NET相关
再过十几天很多同学又要爬楼梯睡觉,早上七点起床,晚
本书根据教育部考试中心2004年最新发布的《全国计算机等级考试大纲》编写,针对计算机等级考试三级网络技术各方面的考点进行讲解
51CTO旗下网站二次元同好交流新大陆
扫码下载App
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
&&&&&&&&上述五个方法和一个属性是最常用、也够用的localStorage的接口,也是所有实现得最为统一的接口。更多其他使用方法,请自行百度查找,这里不一一列举。
&&&&&&&&userData语法略复杂,它需要依赖一个html元素来做代理,该元素需要设定addBehavior('#default#userData'),假设该元素为o,那么如此调用:
1 o.load(dataFile);
2 o.getAttribute(name);
3 o.setAttribute(name, value);
4 o.removeAttribute(name);
5 o.save(dataFile);
&&&&&&&&更多其他接口请参考。
&&&&&&&&兼容方案的目的是:通过对userData的封装,提供一个模拟localStorage对象,实现相同或者高度相似的接口。
&&&&&&&& userData需要指定一个缓存文件(大小限制128k),然后读取指定节点的内容,但是无法遍历缓存文件或节点。网上的兼容方案有两种:
&&&&&&&&1、& 以文件名作为key,自定义一个节点,来保存value
&&&&&&&&2、& 确定一个文件,以节点名作为key,来保存value
&&&&&&&&以文件名作为key的,虽然文件个数不受限制,但是同一域名下有总容量的限制(1024k),同时每个文件最小占用4k(多数系统下),实际文件数不会超过256个,虽然基本够用,但是总归不太好,浪费了不必要的空间(路人甲:哪怕存储一个字符,也要创建一个缓存文件,占用4k的空间,对吧?答:正解。)
&&&&&&&&以节点名作为key的,其灵活性就比较好,一般情况下,单个的key/value都是小量数据,128k的文件上限足够存储数据之用了,所以本文最终采用了以节点名作为key的存储点。
&&&&&&&&有了以上接口,setItem / getItem / removeItem 就很容易实现了,但是仍有两个问题比较棘手:
&&&&&&&&1、& 原生localStorage可以随时使用,但是网上流传的兼容版本必须等页面加载了document.body后才能使用
&&&&&&&&2、& 原生localStorage支持clear方法,以及通过length属性和key方法来实现遍历,网上流传的兼容版本都没有此功能
四、解决方案
&&&&&&&& 首先,要解决访问时机的问题。
&&&&&&&& 网上流传的代码〔节选〕:
1 UserData.o = document.createElement('INPUT');
2 UserData.o.type = "hidden";
3 UserData.o.style.display = "none";
4 UserData.o.addBehavior ("#default#userData");
5 document.body.appendChild(UserData.o);
&&&&&&&&问题出在最后一句,如果document.body不存在,那么这个input也就插入失败,自然就不能继续使用userData,当然,如果你的js放在body标签内,那就可以使用了,但是我喜欢把js放在head内(路人甲:我也喜欢~~)――虽然与google的优化法相左,但是我控制不了自己的洁癖:我觉得放在body内就是污染了body标签,所以我就尝试把input插入到一个已经存在的标签内(哪怕是head),结果居然成功了(路人乙:那你的这个input不也是污染了head标签吗?答:那就不管了,哈哈):
1 var box = document.body || document.getElementsByTagName("head")[0] || document.documentElement,
2 o = document.createElement('input');
3 o.type = "hidden";
4 o.addBehavior ("#default#userData");
5 box.appendChild(o);
6 UserData.o =
&&&&&&& 这样,只要是在组件js下面的任何地方任何时机都可以调用模拟的localStorage组件了,这爽了很多,至少在页面初始化的时候就可以读取一些数据来做一些事情,而不是必须等到页面加载完成才能访问。
&&&&&&& 解决了第一个访问时机的问题后,那如何实现可遍历的功能呢?
&&&&&&& 要遍历,我们就必须要知道以往存储的所有的key,既然userData没有接口提供,那只有我们自己来保存这些key了,存在哪儿?自然还是userData本身。之前提到,用户的key/value存储在一个缓存文件中,那么可以将key存在另外一个缓存文件中,当调用clear方法或者key方法的时候,读取这个keyCache列表就能知道已经存了哪些数据。
&&&&&&& 什么时候更新这个keyCache?当然是 setItem/removeItem 的时候,同理,length属性也是在这两个方法被调用的时候更新的。
&&&&&&& 怎么更新这个keyCache?当然是跟 setItem 一样的逻辑,只是load的文件不同而已。另外,由于只能存储字符串类型的数据,我们就需要把key拼成一个字符串和进行保存,这里又有两个方法:
&&&&&&& 1、& 保存成json串格式的数组。但是key中不能包括引号(可转义)和逗号;
&&&&&&& 2、& 保存成特定分隔符连成的字符串。但是key中不能包含分隔符字符(串);
&&&&&&& 既然第一个处理那么复杂(转义引号、json转化序列化),那不如就用逗号来拼接key来得方便。这因为如此,key就了一个限制:不能包含半角逗号(此限制对一般开发人员来说几乎都是透明的,没听说过谁在变量名中包含逗号)。
&&&&&&& 方法写好了:
cacheKey : function( key, action ){
if( !this.init() )return;
var o = this.o;
//加载keyCache
o.load(this.keyCache);
var str = o.getAttribute("keys") || "",
list = str ? str.split(",") : [],
n = list.length, i=0, isExist = false;
//将key转化为小写进行查找和存储
key = key.toLowerCase();
for(; i&n; i++){
if( list[i] === key ){
isExist = true;
if( action === 2 ){ //如果是删除
list.splice(i,1);
if( action === 1 && !isExist ) //如果是写
list.push(key);
o.setAttribute("keys", list.join(","));
o.save(this.keyCache);
&&&&&& 至此,userData已经完成了最难的两个功能(至少是网上流传版本没有的),剩下的就是简单的setItem / getItem / removeItem功能了,一个函数就可以搞定了。
&&&&&& 这里把源码一并贴出来,并适当进行了一点修改和优化(代码略长,默认给折叠起来了):
1 (function(window, undefined){
2 //如果已经支持了,则不再处理
3 if( window.localStorage )
8 var userData = {
//存储文件名(单文件小于128k,足够普通情况下使用了)
file : window.location.hostname || "localStorage",
//key'cache
keyCache : "localStorageKeyCache",
//keySplit
keySplit : ",",
// 定义userdata对象
init : function(){
if(!this.o){
var box = document.body || document.getElementsByTagName("head")[0] || document.documentElement, o = document.createElement('input');
o.type = "hidden";
o.addBehavior ("#default#userData");
box.appendChild(o);
//设置过期时间
var d = new Date();
d.setDate(d.getDate()+365);
o.expires = d.toUTCString();
//保存操作对象
//同步length属性
window.localStorage.length = this.cacheKey(0,4);
}catch(e){
return false;
return true;
//缓存key,不区分大小写(与标准不同)
1插入key 2删除key 3取key数组 4取key数组长度
cacheKey : function( key, action ){
if( !this.init() )return;
var o = this.o;
//加载keyCache
o.load(this.keyCache);
var str = o.getAttribute("keys") || "",
list = str ? str.split(this.keySplit) : [],
n = list.length, i=0, isExist = false;
//处理要求
if( action === 3 )
if( action === 4 )
//将key转化为小写进行查找和存储
key = key.toLowerCase();
for(; i&n; i++){
if( list[i] === key ){
isExist = true;
if( action === 2 ){
list.splice(i,1);
if( action === 1 && !isExist )
list.push(key);
o.setAttribute("keys", list.join(this.keySplit));
o.save(this.keyCache);
71 //核心读写函数
item : function(key, value){
if( this.init() ){
var o = this.o;
if(value !== undefined){ //写或者删
//保存key以便遍历和清除
this.cacheKey(key, value === null ? 2 : 1);
o.load(this.file);
//保存数据
value === null ? o.removeAttribute(key) : o.setAttribute(key, value+"");
o.save(this.file);
}else{ //读
o.load(this.file);
return o.getAttribute(key) || null;
return null;
clear : function(){
if( this.init() ){
var list = this.cacheKey(0,3), n = list.length, i=0;
for(; i&n; i++)
this.item(list[i], null);
102 //扩展window对象,模拟原生localStorage输入输出
103 window.localStorage = {
setItem : function(key, value){userData.item(key, value); this.length = userData.cacheKey(0,4)},
getItem : function(key){return userData.item(key)},
removeItem : function(key){userData.item(key, null); this.length = userData.cacheKey(0,4)},
clear : function(){userData.clear(); this.length = userData.cacheKey(0,4)},
length : 0,
key : function(i){return userData.cacheKey(0,3)[i];},
isVirtualObject : true
112 })(window);
五、已知问题
&&&&&&&&1、userData在存储节点的时候,不区分大小写,而localStorage区分;这个问题暂时想不到什么好的办法解决。
&&&&&&&&2、模拟localStorage只能清理或遍历通过本组件设定的userData数据,其他方式保存的userData数据无法清理和遍历。
&&&&&&& 3、模拟localStorage的使用和原生localStorage上仍有有效范围的差异。
六、二次包装
&&&&&&&& 我是一个勤奋的懒人,我会为了以后能够偷懒省事儿,我会进一步优化和改善现有的代码,哪怕功能已经够用了,甚至是完备的。
&&&&&&&& localStorage太长,那就用LS!
&&&&&&&& setItem / getItem / removeItem 中的item都是废话(路人甲:是废词。),删掉!
&&&&&&&& length / key 写循环太麻烦,增加each方法!
&&&&&&&& 部分原生的localStorage有bug,修改!
&&&&&&&& 不同浏览器的getItem返回值有细小差异,统一输出!
&&&&&&&& 经常用jQuery/Core(我们自己前端框架的主对象),扩展一个备份!
&&&&&&&& 于是,就有了下面的这个二次包装:
1 (function(window,localStorage,undefined){
2 var LS = {
set : function(key, value){
//在iPhone/iPad上有时设置setItem()时会出现诡异的QUOTA_EXCEEDED_ERR错误
//这时一般在setItem之前,先removeItem()就ok了
if( this.get(key) !== null )
this.remove(key);
localStorage.setItem(key, value);
//查询不存在的key时,有的浏览器返回undefined,这里统一返回null
get : function(key){
var v = localStorage.getItem(key);
return v === undefined ? null :
remove : function(key){ localStorage.removeItem(key); },
clear : function(){ localStorage.clear(); },
each : function(fn){
var n = localStorage.length, i = 0, fn = fn || function(){},
for(; i&n; i++){
key = localStorage.key(i);
if( fn.call(this, key, this.get(key)) === false )
//如果内容被删除,则总长度和索引都同步减少
if( localStorage.length & n ){
31 j = window.jQuery, c = window.C
32 //扩展到相应的对象上
33 window.LS = window.LS || LS;
34 //扩展到其他主要对象上
35 if(j) j.LS = j.LS || LS;
36 if(c) c.LS = c.LS || LS;
37 })(window,window.localStorage);
阅读(654)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_',
blogTitle:'localStorage兼容方案实现',
blogAbstract:'\r\n兼容方案效果:\r\n&&&&&&&&所有主流浏览器支持以下方法和属性:\r\n&&&&&&&&window.localStorage 的 getItem/setItem/removeItem/clear/key 方法以及 length属性\r\n&&&&&&&&window.LS 的 get/set/remove/clear/each 方法\r\n一、引言\r\n&&&&&&&&Web Storage这个东西真正好(路人甲:一头大来一头小…):量大、永久存储、不用使用任何插件,不随http发送 … 用来保存一些用户非敏感的状态和信息是再合适不过的了。其浏览器兼容性如下:\r\n&&&&&&& ',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:2,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&

我要回帖

更多关于 window.localstorage 的文章

 

随机推荐