跳转到主要内容

category

Web开发人员可以使用多种技术将数据存储在用户的浏览器中(即,存储在用户用于查看网站的设备的本地磁盘上)。

浏览器允许网站存储的数据量以及在达到该限制时删除数据的机制因浏览器而异。

本文介绍了可用于存储数据的网络技术,浏览器限制网站存储过多数据的配额,以及它们在需要时删除数据的机制。

浏览器如何将数据从不同的网站中分离出来?


浏览器将来自网站的数据存储在不同的地方,也称为bucket,以降低用户在网络上被跟踪的风险。在大多数情况下,浏览器按每个来源【per origin管理存储的数据。

因此,术语起源对于理解这篇文章非常重要。方案(如HTTPS)、主机名和端口定义。例如,https://example.com和https://example.com/app/index.html属于同一个源,因为它们具有相同的方案(https)、主机名(example.com)和默认端口。

本文中描述的配额和驱逐标准适用于整个来源,即使该来源用于运行多个网站,例如https://example.com/site1/和https://example.com/site2/.

然而,在某些情况下,浏览器可以决定进一步分离源存储在不同分区中的数据,例如,在多个不同的第三方源中的<iframe>元素中加载源的情况下。然而,出于简单的原因,本文假设数据总是按源存储的。

哪些技术将数据存储在浏览器中?


Web开发人员可以使用以下Web技术在浏览器中存储数据:

Technology Description
Cookies An HTTP cookie is a small piece of data that the web server and browser send each other to remember stateful information across page navigation.
Web Storage The Web Storage API provides mechanisms for webpages to store string-only key/value pairs, including localStorage and sessionStorage.
IndexedDB IndexedDB is a Web API for storing large data structures in the browser and indexing them for high-performance searching.
Cache API The Cache API provides a persistent storage mechanism for HTTP request and response object pairs that's used to make webpages load faster.
Origin Private File System (OPFS) OPFS provides a file system that's private to the origin of the page and can be used to read and write directories and files.


请注意,除上述内容外,浏览器还将在浏览器中为源存储其他类型的数据,例如WebAssembly代码缓存。

浏览器存储的数据是否持久?


来源的数据可以通过两种方式存储在浏览器中,即持久和尽最大努力:

  • 尽最大努力:这是默认情况下存储数据的方式。只要来源低于其配额,设备有足够的存储空间,并且用户不选择通过浏览器的设置删除数据,尽力而为的数据就会持续存在。
  • 持久化:源可以选择以持久化的方式存储其数据。只有当用户选择使用浏览器设置时,以这种方式存储的数据才会被收回或删除。要了解更多信息,请参阅何时收回数据。

默认情况下,按来源存储在浏览器中的数据是尽力而为的。当使用IndexedDB或Cache等web技术时,数据是透明存储的,无需征得用户的许可。类似地,当浏览器需要收回尽力而为的数据时,它这样做不会干扰用户。

如果出于任何原因,开发人员需要持久存储(例如,当构建依赖于在其他地方不持久化的关键数据的web应用程序时),他们可以通过使用storage API的navigator.storage.persist()方法来实现。

在Firefox中,当一个网站选择使用持久存储时,用户会收到一个UI弹出窗口,通知用户请求他们的权限。

Safari和大多数基于Chromium的浏览器,如Chrome或Edge,会根据用户与网站的交互历史自动批准或拒绝请求,并且不会向用户显示任何提示。

请注意,Chrome团队的研究表明,浏览器很少删除数据。如果用户定期访问网站,即使在尽力而为的模式下,其存储的数据也很少会被浏览器驱逐。

私人浏览


请注意,在私人浏览模式下(在Chrome中也称为隐姓埋名【Incognito】,在Edge中也称为InPrivate),浏览器可能会应用不同的配额,并且存储的数据通常会在私人浏览方式结束时删除。

可以存储多少数据?


Cookies


不同的浏览器对每个来源允许多少cookie以及这些cookie可以在磁盘上使用多少空间有不同的规则。虽然cookie有助于在页面导航中保留浏览器和web服务器之间的一些小共享状态,但不建议使用cookie在浏览器中存储数据。Cookie是随每个HTTP请求一起发送的,因此将数据存储在可以通过使用另一种网络技术存储的Cookie中会不必要地增加请求的大小。

由于cookie不应用于在浏览器中存储数据,因此此处不包括cookie存储浏览器限制。

Web存储


Web存储可以通过使用窗口对象的localStorage和sessionStorage属性进行访问,在所有浏览器上的最大数据限制为10 MiB。

浏览器最多可存储5 MiB的本地存储空间,每个源最多可存储五MiB的会话存储空间。

一旦达到这个限制,浏览器就会抛出QuotaExceededError异常,应该使用try。。。挡块。

其他web技术


使用其他web技术存储的数据,如IndexedDB、Cache API或文件系统API(定义原始专用文件系统),由每个浏览器特定的存储管理系统进行管理。

该系统使用这些API管理源存储的所有数据。

每个浏览器使用其选择的任何机制来确定给定源可以使用的最大存储量。

Firefox


在Firefox中,源在尽力而为模式下可以使用的最大存储空间是以下两者中较小的一个:

  • 存储用户配置文件的磁盘总大小的10%。
  • 或者10 GiB,这是Firefox适用于同一eTLD+1域中所有来源的组限制。


已授予永久存储的源最多可存储总磁盘大小的50%,上限为8 TiB,并且不受eTLD+1组限制。

例如,如果设备有一个500 GiB的硬盘驱动器,Firefox将允许一个源存储最多:

  • 在尽力而为模式下:10 GiB的数据,这是eTLD+1组的限制。
  • 在持久模式下:250 GiB,相当于磁盘总大小的50%。

请注意,源可能实际上不可能达到其配额,因为它是根据硬盘驱动器的总大小计算的,而不是根据当前可用的磁盘空间计算的。这样做是出于安全考虑,以避免指纹识别。

基于Chrome和Chromium的浏览器


在基于Chromium开源项目的浏览器中,包括Chrome和Edge,一个源可以在持久模式和尽力而为模式下存储高达总磁盘大小的60%

例如,如果设备有一个1TiB的硬盘驱动器,浏览器将允许原点使用高达600GiB的硬盘驱动器。

与Firefox一样,因为这个配额是根据硬盘驱动器的总大小计算的,以避免指纹识别,所以来源实际上可能无法达到其配额。

Safari


从macOS 14和iOS 17开始,Safari为每个源分配高达总磁盘空间20%左右的空间。如果用户已将其保存为主屏幕【Home Screen】或Dock上的web应用程序,则此限制将增加到磁盘大小的60%。出于隐私原因,跨来源框架有一个单独的配额,大约相当于其父母的1/10。

例如,带有1TiB驱动器的macOS设备将每个来源限制在200GiB左右。如果用户在其Dock上存储了一个网络应用程序,则将分配大约600 GiB的更大限制。

与其他浏览器一样,配额强制执行的确切限制可能会有所不同,以避免指纹识别。此外,Safari还强制执行一个总体配额,即所有来源的存储数据不能超过:每个浏览器和网络应用程序的磁盘大小为80%,每个显示网络内容的非浏览器应用程序的硬盘大小为15%。有关Safari存储策略的更多信息,请访问Webkit博客。

在Safari的早期版本中,一个源最初有1GiB的配额。一旦源代码达到此限制,Safari就会请求用户允许源代码存储更多数据。无论源以尽力而为模式还是持久模式存储数据,都会发生这种情况。

如何检查可用空间?


Web开发人员可以使用storage API的navigator.storage.estimate()方法来检查有多少空间可用于源代码,以及源代码使用了多少空间。

请注意,此方法只返回估计的使用值,而不是实际值。由一个来源存储的一些资源可能来自其他来源,并且浏览器在报告总使用价值时自愿填充跨来源数据的大小。

当一个来源地填满其配额时会发生什么?


例如,尝试使用IndexedDB、Cache或OPFS存储多个源配额失败,并出现QuotaExceededError异常。

Web开发人员应该将写入浏览器存储的JavaScript封装在try。。。抓块。还建议在存储新数据之前删除数据以释放空间。

何时收回数据?


数据驱逐是浏览器删除源存储数据的过程。

数据驱逐可能发生在多种情况下:

  • 当设备的存储空间不足时,也称为存储压力。
  • 当浏览器中存储的所有数据(跨所有来源)超过浏览器愿意在设备上使用的空间总量时。
  • 主动地,对于不经常使用的起源,这只发生在Safari中。

存储压力驱逐【Storage pressure eviction


当设备的存储空间(也称为存储压力)不足时,浏览器的可用空间可能会少于存储所有原始存储数据所需的空间。

浏览器使用最近最少使用(LRU)策略来处理这种情况。来自最近最少使用来源的数据将被删除。如果存储压力持续存在,浏览器将移动到最近使用次数第二少的原点,依此类推,直到问题得到解决。

此驱逐机制仅适用于非持久性的起源,并跳过已通过navigator.storage.persist()授予数据持久性的来源。

浏览器最大存储空间已超过逐出


一些浏览器定义了可以在设备硬盘上使用的最大存储空间。例如,Chrome目前最多使用总磁盘大小的80%。

这个最大存储大小意味着,在没有任何一个来源超过其单独配额的情况下,所有组合来源存储的数据可能会超过最大大小。

当这种情况发生时,浏览器开始驱逐尽力而为的来源,如存储压力驱逐中所述。

主动驱逐【Proactive eviction


Safari在启用跨站点跟踪保护时会主动收回数据。如果源在浏览器使用的最后七天内没有用户交互,如点击或点击,则其根据脚本创建的数据将被删除。服务器设置的Cookie不受此驱逐的约束。

如何收回数据?


当浏览器收回来源的数据时,会同时删除其所有数据,而不是部分数据。例如,如果源通过使用IndexedDB和Cacheneneneba API存储数据,那么这两种类型的数据都将被删除。

仅删除部分源数据可能会导致不一致性问题。

另请参阅