HTML5 localStorage.setItem 不适用于 iOS 8 - Safari mobile

Man*_*ndy 2 javascript local-storage ios8.3

localStorage.setItem 不适用于移动 iOS 8.3。

有人遇到过这个问题吗?
这是代码:

var storage = window.localStorage;
storage.setItem('test',45);
alert(storage.getItem('test'));
Run Code Online (Sandbox Code Playgroud)

J L*_*tle 5

过去,我们可以使用类似的东西:

if ('localStorage' in window && window.localStorage !== null) {
    alert('can use');
}else{
    alert('cannot use');
}
Run Code Online (Sandbox Code Playgroud)

或者

if (localStorage === undefined) {... }
Run Code Online (Sandbox Code Playgroud)

但是,在 iOS 8.3+ 中,当用户禁用 cookie 时,此代码会引发未处理的 JavaScript 错误。当用户进入隐私浏览模式时,当您尝试写入 localStorage 时会出现相同的错误消息。

SecurityError: DOM Exception 18: 试图突破用户代理的安全策略。



解决方法

为了避免由于 iOS 的这种特殊行为而导致的不必要的 JavaScript 错误,一个建议是将其包含在 try catch 块中。(至少目前是这样)

try{
  if ('localStorage' in window && window.localStorage !== null) {
    localStorage.setItem('testLocalStorage', 'testLocalStorage');
    if (localStorage.getItem('testLocalStorage') !== 'testLocalStorage') {
        localStorage.removeItem('testLocalStorage');
        //for private browsing, error is thrown before even getting here
        alert('can read CANNOT write'); 
    }else{
        localStorage.removeItem('testLocalStorage');
        alert('can use');
    }
  }else{
    alert('CANNOT use');
  }
}catch(ex){
  alert('CANNOT use reliably');
}
Run Code Online (Sandbox Code Playgroud)

注意:这不是在您的实际代码中使用警报的建议。这只是为了快速说明。



可能的简写

try {
    localStorage.setItem('testLocalStorage', 'testLocalStorage');
    localStorage.removeItem('testLocalStorage');
    alert('supported');
} catch(ex) {
    alert('unsupported');
}
Run Code Online (Sandbox Code Playgroud)



我们可以用什么代替

对于不支持 localStorage 的情况,可能的替代方案包括服务器会话(如果不支持 cookie,则基于 URL 参数)或用于存储序列化数据的 window.name 变量。

或者,如果您设计和构建为单页应用程序,也许您根本不需要将数据存储在全局命名空间中。