检查 localStorage 是不是可用
Posted
技术标签:
【中文标题】检查 localStorage 是不是可用【英文标题】:Check if localStorage is available检查 localStorage 是否可用 【发布时间】:2013-05-01 21:55:51 【问题描述】:我知道有很多关于检查 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!');
【问题讨论】:
仍然没有提供任何方法来查看它是否工作...... 嗯嗯嗯。如果它抛出一个异常你知道它不工作 How to detect if browser supports html5 Local Storage的可能重复 Check for HTML 5 localStorage的可能重复 【参考方案1】:使用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” @user2025469 此代码旨在用作函数。 对不起,我应该提到这一点。我已经更新了我的答案并添加了一个演示,以便您可以看到它正常工作。 乔,这正是我一直在寻找的。当我打开 LS 时,它会提示不可用。这只是一个基本的javascript函数还是我需要在我的脚本中包含modernizr JS> 当心!如果达到 localStorage 配额,此 Modernizr 方法将返回 false。如果您有处理 localStorage 清理的函数,您应该编辑 catch 语句以在异常名称e.name ==== 'QUOTA_EXCEEDED_ERR'
(Chrome) 或 'NS_ERROR_DOM_QUOTA_REACHED'
(Firefox/Safari) 或 IE 中的 localStorage.remainingSpace === 0
时启动适当的清理操作。【参考方案2】:
我会检查 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
【讨论】:
在给定的情况下,这只是一个可以防止其他浏览器出错的功能......所以这并不能真正回答这个问题。如果关闭,localStorage
仍然在 window
中定义。
你仍然得到一个 DOM 错误......我简直不敢相信没有办法检查它是否完全关闭......
这对 Chrome 和 Opera 来说不是一种安全的方法...可能也不是 Safari,因为 localStorage
完全无法访问并且会引发异常。
您不需要所有这些else
s... 只需一个 try catch 就可以了。我看到你正在测试结果实际上是'yes'
,但我没有任何实际需要的用例。【参考方案3】:
功能检测本地存储很棘手。你需要真正进入它。这样做的原因是 Safari 选择在私有模式下提供功能性 localStorage
对象,但它的配额设置为零。这意味着虽然所有简单的功能检测都会通过,但对localStorage.setItem
的任何调用都会引发异常。
Mozilla 在 Web Storage API 上的开发者网络条目有一个dedicated section on feature detecting local storage。这是该页面上推荐的方法:
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,你可以使用 storage-available 获取
npm install -S storage-available
然后像这样使用函数:
if (require('storage-available')('localStorage'))
// Yippee! We can use localStorage awesomeness
免责声明:MDN 上的文档部分和 NPM 包均由我撰写。
【讨论】:
最佳答案,谢谢 Stijn。【参考方案4】:MDNupdated存储检测功能。 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,这仅意味着我们已经用完了所有可用的存储空间,但存储实际上是可用。我们的特征检测应该考虑到这些场景。
在此处查看brief history of feature-detecting localStorage。
【讨论】:
这不是我在带有 ios 12.1 的 Safari 中看到的确切行为。我可以设置并检索它们 - 在我关闭该选项卡后它们不会持续存在。即使我在同一选项卡中访问另一个网站并返回,我保存的数据仍然存在。所以不确定这条评论有多久了。 显然这是一个已修复的错误 - ***.com/questions/14555347/…。必须假设您的用户是否处于私人模式,他们希望在离开并回来时失去“会话”。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 的行为:它会起作用,但前提是浏览器保持打开状态。
在移动设备上使用 Safari 私有模式时尝试从本地存储写入或读取时没有收到任何错误。 Safari 将什么也不做,默默地失败。【参考方案5】:
使用此功能,您可以检查本地存储是否可用,并控制可能的异常。
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;
【讨论】:
【参考方案6】:修改 Joe 的答案以添加 getter 使其更易于使用。用下面你简单地说:if(ls)...
Object.defineProperty(this, "ls",
get: function ()
var test = 'test';
try
localStorage.setItem(test, test);
localStorage.removeItem(test);
return true;
catch(e)
return false;
);
【讨论】:
为什么投反对票?它有效,并且输入ls
比输入lsTest() === true
更好。 ...?
它不起作用。您正在将一个对象分配给ls
...,因此if (ls)
将始终评估为true
。只需通过将get
方法更改为get: function()return false
来检查它,您就会看到。此外,输入ls
也不是更好......这个测试在你的代码中不会太频繁(如果你以一种聪明的方式编写它),那么为什么用一个非常短的变量来污染(全局)范围呢?
你的权利。我必须解决这个问题...谢谢!
@StijndeWitt 现在可以使用了。感谢您的反馈...就污染全球范围而言,我理解您的观点,但我认为这是一种观点。有人可能会发现输入if(ls)...
是值得的。
` === true` 不再需要检查函数结果而不是 getter 结果。键入lsTest()
比ls
更好,因为它更具描述性,而isLocalStorageAvailable()
会更好。最好避免使用 getter,因为它们可能会令人惊讶,因为没有迹象表明它会在键入(例如)ls
时执行代码。这里没有理由使用吸气剂。如果您真的不想要括号,您可以只计算一次可用性并将结果存储在全局变量中。然后考虑起来更简单(没有隐藏执行)并且整体更短。【参考方案7】:
最好结合cookies
检查localStorage
的可用性,因为如果启用cookie
,浏览器可以检测到localStorage
可用并且type
它是object
,但不提供使用它的可能性。您使用下一个函数来检测localStorage
和cookies
:
const isLocalStorage = () =>
try
if (typeof localStorage === 'object' && navigator.cookieEnabled) return true
else return false
catch (e)
return false
【讨论】:
正如另一个答案中所解释的,这是一个 Safari 错误,它在隐私浏览时将 localStorage 设置为一个空对象。浏览器不应该这样做。 Cookies 和 localStorage 是完全不同的机制。 这不是 Safari 错误。您可以在 Chrome 中查看,禁用 cookie 并重试【参考方案8】:这是一个简单的检查:
if(typeof localStorage === 'undefined')
【讨论】:
localStorage
的类型返回object
,即使它在 Firefox 或 IE 中被禁用。在 Chrome 和 Opera 中,typeof
会在用户将其关闭时引发异常并破坏整个脚本...
在 Safari 的隐私浏览模式下,您会得到一个有效的 localStorage
对象,其配额为零,因此每当您尝试写入它时都会引发异常。这就是为什么本地存储功能检测代码现在总是尝试写入项目。【参考方案9】:
使用它来检查是否设置了 localStorage。它可以帮助您获取 Localstorage 的状态。
if( window.localStorage.fullName !== undefined)
//action
else
【讨论】:
访问localStorage不需要等待文档加载完成(所以$()
没有意义)更重要的是,如果localStorage不可用,这段代码会报错。
实际上,Mozilla 文档声明 localStorage
本质上是同步的,因此它可以阻止主文档的呈现。因此,等待它准备好将是一个好方法。
他们说localStorage
是同步的意思是localStorage.getItem('someKey')
实际上立即返回该项目。它不接受回调函数或返回Promise
,它只是立即返回数据。将其与例如var result = fetch('https://example.com/data.json')
... 返回一个 Promise
,使其异步。您必须调用 then
方法来获取数据(只会在下一个刻度发生):result.then(function(data) /* only here do we get the data */ )
这是关于同步调用阻塞渲染的事实,中断了对页面的进一步解析。回调行为在这里无关紧要。以上是关于检查 localStorage 是不是可用的主要内容,如果未能解决你的问题,请参考以下文章
HTML5 LocalStorage:检查密钥是不是存在[重复]