检查 localStorage 是否可用

IT技术 javascript error-handling local-storage
2021-02-13 15:44:08

我知道有很多关于检查的问题,localStorage但是如果有人在浏览器中手动关闭它怎么办?这是我用来检查的代码:

localStorage.setItem('mod', 'mod');
if (localStorage.getItem('mod') != null){
  alert ('yes');
  localStorage.removeItem('mod');
} else {
  alert ('no');
}

简单的功能,它的工作原理。但是,如果我进入 Chrome 设置并选择“不保存数据”选项(我不记得它的确切名称),当我尝试运行此功能时,除了Uncaught Error: SecurityError: DOM Exception 18. 那么有没有办法检查这个人是否完全关闭了它?

更新:这是我尝试的第二个功能,但我仍然没有得到响应(警报)。

try {
  localStorage.setItem('name', 'Hello World!');
} catch (e) {
  if (e == QUOTA_EXCEEDED_ERR) {
   alert('Quota exceeded!');
  }
}
6个回答

使用modernizr的方法(您可能希望将我的函数名称更改为更好的名称):

function lsTest(){
    var test = 'test';
    try {
        localStorage.setItem(test, test);
        localStorage.removeItem(test);
        return true;
    } catch(e) {
        return false;
    }
}

if(lsTest() === true){
    // available
}else{
    // unavailable
}

它不像其他方法那样简洁,但这是因为它旨在最大限度地提高兼容性。

原文出处:https : //github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js

工作示例:http : //jsfiddle.net/6sm54/2/

嘿乔,我在运行你的函数时遇到这个错误(LS 打开或关闭)“Uncaught SyntaxError: Illegal return statement”
2021-03-29 15:44:08
谨防!如果达到 localStorage 配额,此 Modernizr 方法将返回 false。如果你有处理 localStorage 清理的函数,你应该编辑 catch 语句以启动适当的清理操作,如果异常名称e.name ==== 'QUOTA_EXCEEDED_ERR'(Chrome) 或'NS_ERROR_DOM_QUOTA_REACHED'(Firefox/Safari) 或者如果localStorage.remainingSpace === 0在 IE 中。
2021-04-02 15:44:08
@user2025469 此代码旨在用作函数。
2021-04-05 15:44:08
抱歉,我应该提到这一点。我已经更新了我的答案并添加了一个演示,以便您可以看到它正常工作。
2021-04-14 15:44:08
乔,这正是我一直在寻找的。当我关闭 LS 时,它会提示不可用。这只是一个基本的javascript函数还是我需要在我的脚本中包含modernizr JS>
2021-04-14 15:44:08

我会localStorage在任何依赖于它的操作之前检查它的定义:

if (typeof localStorage !== 'undefined') {
    var x = localStorage.getItem('mod');
} else {
    // localStorage not defined
}

更新:

如果您需要验证该功能是否存在并且它也未关闭,则必须使用更安全的方法。为了完全安全:

if (typeof localStorage !== 'undefined') {
    try {
        localStorage.setItem('feature_test', 'yes');
        if (localStorage.getItem('feature_test') === 'yes') {
            localStorage.removeItem('feature_test');
            // localStorage is enabled
        } else {
            // localStorage is disabled
        }
    } catch(e) {
        // localStorage is disabled
    }
} else {
    // localStorage is not available
}
你仍然收到一个 DOM 错误......我简直不敢相信没有办法检查它是否完全关闭......
2021-03-24 15:44:08
这对于 Chrome 和 Opera 来说不是一种安全的方法......可能也不是 Safari,因为localStorage它完全无法访问并且会抛出异常。
2021-03-25 15:44:08
您不需要所有这些else...只需一次 try catch 即可。我看到您正在测试结果实际上是'yes',但我没有任何实际需要的用例。
2021-03-28 15:44:08
在给定的情况下,这只是一个可以防止其他浏览器出错的功能……所以这并不能真正回答问题。如果关闭,localStorage仍然在 中定义window
2021-04-06 15:44:08

特征检测本地存储很棘手。你需要真正接触它。这样做的原因是 Safari 选择localStorage在私有模式下提供一个功能对象,但它的配额设置为零这意味着尽管所有简单的功能检测都会通过,但任何调用localStorage.setItem都会抛出异常。

Mozilla 的 Web Storage API 上的 Developer Network 条目有一个关于功能检测本地存储专门部分这是该页面上推荐的方法:

function storageAvailable(type) {
    try {
        var storage = window[type],
            x = '__storage_test__';
        storage.setItem(x, x);
        storage.removeItem(x);
        return true;
    }
    catch(e) {
        return false;
    }
}

这是您将如何使用它:

if (storageAvailable('localStorage')) {
    // Yippee! We can use localStorage awesomeness
}
else {
    // Too bad, no localStorage for us
}

如果您使用NPM,你可以抓住存储提供使用

npm install -S storage-available

然后像这样使用函数:

if (require('storage-available')('localStorage')) {
    // Yippee! We can use localStorage awesomeness
}

免责声明:关于 MDN 和 NPM 包的文档部分都是由我创作的。

最佳答案在这里,谢谢 Stijn。
2021-03-29 15:44:08

MDN更新了存储检测功能。在 2018 年,它更可靠:

function storageAvailable() {
    try {
        var storage = window['localStorage'],
            x = '__storage_test__';
        storage.setItem(x, x);
        storage.removeItem(x);
        return true;
    }
    catch(e) {
        return e instanceof DOMException && (
            // everything except Firefox
            e.code === 22 ||
            // Firefox
            e.code === 1014 ||
            // test name field too, because code might not be present
            // everything except Firefox
            e.name === 'QuotaExceededError' ||
            // Firefox
            e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
            // acknowledge QuotaExceededError only if there's something already stored
            storage && storage.length !== 0;
    }
}

支持 localStorage 的浏览器将在名为 localStorage 的窗口对象上有一个属性。但是,由于各种原因,仅仅断言属性存在可能会引发异常。如果确实存在,那仍然不能保证 localStorage 实际上可用,因为各种浏览器提供禁用 localStorage 的设置。因此,浏览器可能支持localStorage,但不使其用于页面上的脚本。一个例子是 Safari,它在隐私浏览模式下为我们提供了一个空的 localStorage 对象,其配额为零,实际上使其无法使用。但是,我们可能仍然会得到一个合法的 QuotaExceededError,这仅意味着我们已经用完了所有可用的存储空间,但存储实际上是可用的. 我们的特征检测应该考虑到这些场景。

有关特征检测 localStorage简要历史,请参见此处

这不是我在 iOS 12.1 的 Safari 中看到的确切行为。我能够设置并检索它们 - 在我关闭该选项卡后它们不会持续存在。即使我在同一选项卡中访问另一个网站并返回,我保存的数据仍然存在。所以不确定这个评论有多老。
2021-03-29 15:44:08
This isn't the exact behavior I'm seeing in Safari with iOS 12.1. I'm able to set things and retrieve them - they just don't persist after I close that tab. 是的。值得庆幸的是,WebKit 开发人员变得聪明并改变了错误的行为。在旧版本中,它们会在私有模式下抛出配额超出错误以及任何写入 localStorage 的尝试。这是出乎意料的,给开发人员带来了很多问题。在以后的版本中,他们对其进行了更改以匹配其他浏览器和 cookie 的行为:它可以工作,但仅在浏览器保持打开状态时有效。
2021-04-10 15:44:08
显然,这是是自修正了一个错误- stackoverflow.com/questions/14555347/...必须假设您的用户是否处于私人模式,他们希望在离开和回来时失去“会话”。
2021-04-13 15:44:08
在移动设备上使用 Safari 私有模式尝试写入或读取本地存储时,我没有收到任何错误。Safari 不会做任何事情并且默默地失败。
2021-04-13 15:44:08

使用此功能,您可以检查 localstorage 是否可用,并控制可能出现的异常。

function isLocalStorageAvailable() {

    try {
        var valueToStore = 'test';
        var mykey = 'key';
        localStorage.setItem(mykey, valueToStore);
        var recoveredValue = localStorage.getItem(mykey);
        localStorage.removeItem(mykey);

        return recoveredValue === valueToStore;
    } catch(e) {
        return false;
    }
}