本地存储没有简单的解决方案

TL;DR: 我们必须停止提倡 localStorage 作为存储数据的绝佳机会,因为它性能很差。不幸的是,替代方案的支持程度或实现难度都远远不如。

在网页开发中,你总是会遇到一些看似好得令人难以置信的事情。有时它们确实很好,阻止我们使用它们的原因是我们作为开发者对*所有*事物的谨慎态度。然而,在很多情况下,它们实际上并没有看起来那么好,直到我们用了一段时间之后才发现自己其实“做错了”。

本地存储就是一个这样的例子。存在一个 存储规范(在很多例子中被错误地归因于 HTML5),它有一个极其简单的 API,在发布时被誉为是“cookie 杀手”。要将内容存储在用户的机器上,你只需要访问 navigator.localStorage(或者如果你不需要将数据存储在当前浏览器会话之外,则访问 sessionStorage)。

localStorage.setItem( 'outofsight', 'my data' );
console.log( localStorage.getItem( 'outofsight' ) ); // -> 'my data'

这种本地存储解决方案对网页开发者来说具有几个非常诱人的功能。

  • 它非常简单。
  • 它使用字符串来存储数据,而不是复杂的数据库(你可以使用 JSON 编码来存储更复杂的数据)。
  • 它得到了 浏览器的良好支持
  • 它得到了许多公司的认可(并且在 iPhone 发布时被誉为是“惊世之作”)。

一些已知的问题是,没有干净的方法来检测何时达到本地存储的限制,并且没有跨浏览器的办法来请求更多空间。还有一些关于会话和 HTTPS 的 不为人知的问题,但这仅仅是冰山一角。

主要问题:性能糟糕

LocalStorage 还有一些没有很好记录的缺点,当然在“HTML5 教程”中也没有充分地介绍这些缺点。特别是注重性能的开发者强烈反对使用它。

几周前,当我们介绍了使用 localStorage 来 在 localStorage 中存储图像和文件 时,它引发了大量的评论,并在内部邮件列表中引发了更长篇幅的讨论,关于 localStorage 的弊端。主要问题是:

  • localStorage 本质上是同步的,这意味着当它加载时,它会阻止主文档渲染。
  • localStorage 进行文件 I/O 操作,这意味着它写入你的硬盘驱动器,这可能需要很长时间,具体取决于你的系统执行的操作(索引、病毒扫描等)。
  • 在开发人员的机器上,这些问题可能看起来微不足道,因为操作系统缓存了这些请求 - 对于网络上的最终用户来说,这可能意味着等待几秒钟,在此期间网站会停滞。
  • 为了看起来更流畅,网页浏览器会在第一次请求时将数据加载到内存中 - 如果有很多选项卡这样做,这可能意味着会占用大量内存。
  • localStorage 是持久化的。如果你不再使用某个服务,或者不再访问某个网站,当你启动浏览器时数据仍然会被加载。

Mozilla 性能团队的 Taras Glek 以及诺基亚的 Andrea Giammarchi 在后续的博客文章中详细地介绍了这个问题。

从本质上讲,这意味着很多文章说你可以使用 localStorage 来提高性能是错误的。

替代方案

当然,浏览器一直都提供了一些存储本地数据的办法,其中一些你可能从未听说过,比如 evercookie(我认为,在“没有现实用途的邪恶天才”因素方面,我最喜欢的是用 force-cached PNG 图像来读取 canvas 中的数据)。在内部讨论中,人们大力提倡使用 IndexedDB 而不是 localStorage。然后我们 发布了一篇文章,介绍如何在 IndexedDB 中存储图像和文件,并且发现了一些问题 - 大部分问题实际上与易用性和用户交互有关。

  • IndexedDB 是一个功能齐全的数据库,它需要像 SQL 数据库一样执行所有步骤来读写数据 - 并没有像 localStorage 那样提供简单的键值层。
  • IndexedDB 会向用户请求存储数据的权限,这可能会吓到他们。
  • 浏览器的支持程度与 localStorage 完全不同,目前 IndexedDB 支持 IE10、Firefox 和 Chrome,并且它们之间存在实现差异。
  • Safari、Opera、iOS、Opera Mobile、Android 浏览器更倾向于使用 WebSQL(这是 另一个标准,它已经被 W3C 正式弃用)。

就像往常一样,当实现之间存在差异时,就会有人提出抽象层来解决这个问题。Parashuram Narasimhan 在这方面做得很好 - 甚至提供了一个 jQuery 插件。但感觉我们作为实现者不得不使用这些工具是错误的。这就像 WebM 与 H264 之间的 HTML5 视频之争,只不过又上演了一次。

现在怎么办?

毫无疑问,真正的数据库解决方案及其异步性质在性能方面是更好的选择。它们也更加成熟,并且没有 localStorage 的那种“捷径 hack”的感觉。另一方面,它们比 localStorage 更难使用,我们已经有了很多使用 localStorage 的解决方案,而要求用户授予我们存储本地文件的权限对于某些实现来说在 UX 方面是不可接受的。

答案是,在用户的机器上存储数据没有简单的解决方案,我们应该停止提倡 localStorage 作为性能提升的手段。我们需要找到一个让所有人都满意,并且不会破坏现有实现的解决方案。这可能很难解决。以下是一些想法:

  • 创建一个覆盖 localStorage API 的 polyfill 库,并将内容存储在 IndexedDB/WebSQL 中?这很脏,并且无法解决用户被要求授予权限的问题。
  • 在浏览器中以异步方式实现 localStorage - 积极地无视规范?(但这可能开创一个危险的先例)。
  • 更改 localStorage 规范,使其以异步方式存储,而不是同步存储?我们还可以对其进行扩展,使其具有适当的 getStorageSpace 接口,并允许本机 JSON 支持。
  • 定义一个新的标准,允许浏览器供应商将新 API 映射到现有支持的 API,以便最适合用例?(

我们需要解决这个问题,因为在本地存储数据的同时牺牲性能是毫无意义的。这是一个很好的例子,说明新的网页标准为我们提供了更多强大的功能,但也让我们面对以前不必处理的问题。随着对操作系统的访问权限越来越大,我们也必须更加谨慎。

关于 Chris Heilmann

HTML5 和开放网页的布道者。让我们来修复这个问题!

更多 Chris Heilmann 的文章…


124 条评论

  1. Pete

    我们有一个很棒的规范 WebSQL,但是由于 Mozilla 决定引入 IndexDB,现在出现了碎片化。由于 IndexDB 并不是一个更容易的替代品,而只是一个功能更弱的替代品,因此你现在无法抱怨这种情况。
    恭喜!

    2012 年 3 月 5 日 下午 03:16

    1. Ron

      我不认为 IndexedDB 功能更弱。将 IndexedDB 与 WebSQL 进行比较就像在服务器端讨论 NoSQL 与 SQL 数据库一样。它们都有自己的优势,如果你选择了合适的存储机制,某些工作负载的性能会好得多。

      当然,可以模拟 WebSQL-via-IndexedDB,就像现在可以模拟 IndexedDB-via-WebSQL 一样。我期待着供应商前缀被删除,这样我们就可以放心地使用 IndexedDB。

      2012 年 3 月 5 日 下午 03:24

    2. Chris Heilmann

      “该文档曾经位于 W3C 建议路径上,但规范工作已停止。规范陷入了僵局:所有感兴趣的实现者都使用相同的 SQL 后端(Sqlite),但我们需要多个独立的实现才能继续沿着标准化路径发展。”

      我当然可以抱怨 - 我是一个开发者,我希望得到简单易用且有效的工具。WebSQL 并不是一个面向网页的数据库,它很复杂,而 Sqlite 会带来很多问题。如果写入被认为是损坏的,数据库就会被清空 - 这不是一个值得信赖的东西。问问任何使用 Mail.app 并丢失了存档的用戶就知道了。

      此外,这是关于如何提高 localStorage 的性能,而 IndexedDB 的实现数量远远不足。

      2012 年 3 月 5 日 下午 03:33

      1. Pete

        当然你可以抱怨。我只是不想在这里发泄。只是这里有一点沮丧。实际上,我们公司决定为内部网使用 WebSQL,并建议使用 Chrome。由于我们从 0.x 版本开始就一直使用 Gecko,所以这是一个痛苦的决定,但这就是生活……

        2012 年 3 月 5 日 下午 03:37

        1. Chris Heilmann

          那么你的公司正在支持一项过时的技术 - 我不会感到惊讶,如果 Chrome 在未来取消支持,考虑到 Google 正在进行的 IndexedDB 工作。这是一个需要标记的事情 :)

          2012 年 3 月 5 日 下午 03:41

          1. Pete

            好吧,考虑到有许多 WebSQL 项目未被使用,他们不能简单地拔掉插头。只要 Apple 在 iOS 上大力支持它,他们也不能在短期或中期内将其从主机中删除。
            所以,现在,它是合适的技术。但我同意,你永远不知道未来会发生什么。

            2012 年 3 月 5 日 下午 03:46

      2. X

        Chris: 我很抱歉,但是你认为 SQL(ite) “复杂” 以及你认为它“会造成很多问题”这一事实并不意味着它不适合客户端 Web。它只是意味着你需要学习 SQL(ite)。

        2012 年 3 月 13 日 下午 02:52

    3. Alex

      Web SQL 数据库实际上只是一个规范,它说你“必须实现 Sqlite 3.6.19 支持的 SQL 方言”。它不是一个“好的规范” - 现在它是一个被废弃的规范 - 因为没有 W3 建议曾经建议过只有一种实现的东西,更不用说一个特定的 bugfix 版本了。他们已经尽一切努力编写自己的 Web 服务器和浏览器来解决这个问题。然而,没有一个开始实施 Web SQL 的供应商费心开始一个替代的实现。

      几年前,他们非常简单地告诉大家该怎么做才能使其继续前进:“我们需要多个独立的实现才能沿着标准化路径前进”。没有人关心去做这件事,所以你现在不能抱怨这种情况。

      2012 年 3 月 5 日 上午 10:12

    4. Les Orchard

      你搞错了。IndexedDB 的引入是因为 WebSQL 不是一个好的规范。

      除非你的意思是“使用方便”,这与“好的规范”不同。一个好的规范理想情况下应该引入一个易于使用的 API,但它也不应该耸耸肩,并包含一个特定于供应商的含糊不清的东西,比如“用户代理必须实现 Sqlite 3.6.19 支持的 SQL 方言”。

      2012 年 3 月 5 日 下午 14:25

  2. Ron

    我很高兴我不是唯一一个对当前 HTML5 存储状态深感担忧的人。

    我对所有 IndexedDB 支持者感到恼火,因为主要的 WebKit 浏览器都没有支持它(尽管 Android 5.0 如果 Google 完全切换到 Chrome,可能会支持它)。规范仍然是草案,目前的实现仍然带有供应商前缀:我不想依赖它来进行生产 Web 应用程序。

    为什么主要的 Web 浏览器没有提供一个像样的配额增加 API?这是一个非常短视的决定,我们都将不得不忍受很长时间(因为移动手机软件比台式机软件有更长的生命周期)。

    我在 Mozilla 提交了一个 bug 报告,要求将配额增加行为扩展到现有的存储机制(即 localStorage),他们嘲笑我。mozIndexedDB 已经拥有灵活的用户允许的配额增加,而没有人有兴趣在同时修复 localStorage。祝你的 B2G 和 Web API 计划在完全没有稳定的存储 API 的情况下好运。

    我在 Chromium 提交了一个类似的 bug 报告,他们的全新 Storage Quota API 看起来不会很快扩展到 WebSQL 或 localStorage(尽管根据白皮书,这在某个时候似乎是一个长期目标)。

    作为一名为专业企业移动性开发移动 Web 应用程序的开发者,这对我是个巨大的问题。我觉得 Web 应用程序非常接近成为原生应用程序的合格替代品,但因为这个令人痛苦的明显遗漏。

    抱歉发泄了,但我每天都在努力解决这个问题,我对 W3C 和浏览器供应商事先没有解决这个问题感到愤怒。

    2012 年 3 月 5 日 下午 03:20

    1. Jonas Sicking

      我知道 Google 对 localStorage 的性能与我们 Mozilla 一样关心。这可能是他们没有将配额规范扩展到 localStorage 的原因。(在那里存储更多数据只会使性能更差)。

      至于他们为什么没有将其扩展到 WebSQL,你的猜测和我一样好。但我注意到他们正在大力投资 IndexedDB。

      2012 年 3 月 6 日 下午 03:14

  3. Sean Hogan

    为什么 LocalStorage 比访问浏览器的 URL 缓存更慢?

    Sean

    2012 年 3 月 5 日 下午 03:41

  4. Marcel Jackwerth

    我认为 localStorage 的 polyfill 是不可能的,因为我们无法在没有第二个线程的情况下伪造同步 API。如果 localStorage API 是异步的,它可以用 IndexedDB/WebSQL 来模拟,这本身就是反对它独立存在的理由。

    LocalStorage 的(简单)同步特性以及 JS 中的异步编程并不有趣/很麻烦(与 Go/C#5 相比)使得现在很难反对它。Harmony 甚至没有在路线图上包含任何与异步相关的功能,让我们只能使用 StreamlineJS、TameJS、IcedCoffeeScript 和 Dart(带有一个实验性的 `async` 关键字)。

    2012 年 3 月 5 日 下午 03:50

    1. Burak Yiğit Kaya

      Harmony 实际上带有一个类似于 Python 的 `yield` 关键字,可以用来通过像 TaskJS 这样的库来缓解异步编程的痛苦,如果我理解你的担心的话。

      2012 年 3 月 5 日 上午 06:42

  5. Christopher Biscardi

    LocalStorage 是用来作为文件/blob 存储的吗?我一直以为它是一个简单的键值存储,用于存储 json 字符串化的数据等等。
    当不存储文件时,这些问题还会出现吗?

    2012 年 3 月 5 日 下午 04:11

    1. Robert Nyman

      正如你所说,它被设计成一个简单的键值存储,但已被用于很多事情 - 我想主要是由于缺乏其他可行的选择。

      在性能方面,无论你想存储什么,都是同一个问题。你实际上不能存储文件,只能存储 Data URL 作为字符串。

      2012 年 3 月 5 日 下午 04:21

  6. Remy Sharp

    我仍然犹豫是否真的需要淘汰 localoStorage,主要是因为 IndexedDB 还没有没有供应商前缀的情况下发布,调试工具也不存在,开发者很难使用(API 设计的可访问性将是成功的因素 - 但同意在 localStorage 之上使用指向 IndexedDB 的 polyfill 可能是优雅的解决方案)。

    无论如何,我想澄清(或者询问你的意见)的是,你反对 localStorage,但是 sessionStorage 呢?由于数据持久化的方式,它不适合存储大量数据,因此开发人员更有可能将其用于存储少量数据。当然,它仍然会阻塞 - 这就是为什么我想要弄清楚你是否主张“停止使用 localStorage”或“停止使用 WebStorage”。

    2012 年 3 月 5 日 下午 04:24

  7. pd

    感谢你对这个主题的诚实和现实的看法。

    2012 年 3 月 5 日 下午 04:32

  8. Moldován Eduárd

    嘿,伙计们,

    有一件事我不理解。我不是 localStorage 专家,但是为什么浏览器在加载页面时加载任何数据?
    我想一个可能的答案是 localStorage 引擎在页面加载期间启动。如果是这样,为什么它不能在页面加载后启动?
    很多其他事情如果在错误的时间进行会使文档渲染变慢。

    我对答案非常好奇。

    干杯,
    edi

    2012 年 3 月 5 日 下午 04:32

    1. Marcel Jackwerth

      localStorage 有一个同步 API。如果数据没有预先加载,那么任何获取值的调用都可能阻塞整个 UI 线程几毫秒(甚至几秒)。所以实际上这是一个浏览器供应商用来弥补 localStorage API 缺陷的解决方法(在本文的“主要问题:糟糕的性能”中讨论)。

      2012 年 3 月 5 日 下午 04:47

      1. Moldován Eduárd

        好吧,这个解决方法实际上不是解决方法。在我看来,当我加载一个页面并且它挂起了几秒钟,我就离开了,再也不会回来。如果我在页面上工作,做一些事情,然后它挂起了一段时间,告诉我它正在加载一些东西,我就接受了,因为我要求它为我做一些事情。
        这可能是一个非常简化的观点,但可能有效。你对此怎么看?

        2012 年 3 月 5 日 上午 06:01

  9. Jens Arps

    我 פשוט לא מבין את כל תנועת "אנטי-localStorage". ואני לא ראיתי עדיין טיעונים ששכנעו אותי להפסיק להמליץ ​​על localStorage. כמו שעשיתי הרבה פעמים בעבר, אני רוצה להתייחס לשתי הבעיות הנפוצות ביותר עם ls

    – Performance: localStorage outperforms _any_ other storage engine, including IDB. See http://jsperf.com/indexeddb-vs-localstorage/2

    – Blocking: I just have not seen localStorage really blocking or hanging the UI in the real world yet.

    Currently, there just isn’t a feasible alternative to ls. IndexedDB might become one, given that
    – the spec is stable
    – all major browser vendors have a plugin-free impl
    – there are easy-to-use wrappers for it
    – it’s available on mobile devices (well, would at least be nice to have)

    所以,我们现在能做的就是鼓励人们查看 IDB,试用它,并对 API 有个直观的了解。我们需要优秀且有效的教程,以及可用的封装库。目前,情况很尴尬:大多数 IDB 封装库都无法正常工作,大多数教程也无法正常工作。规范经常发生变化(我自己也难以让 IDBWrapper 保持最新),而新的版本控制 API 使得动态使用 IDB 几乎不可能。

    当有人问我现在生产环境中应该使用什么存储引擎时,我会告诉他们使用 localStorage。因为没有替代方案,而且我认为 localStorage 并没有什么不好。

    2012 年 3 月 5 日 下午 5:35

    1. Jonas Sicking

      你说你还没有在“现实世界”中看到 localStorage 阻塞,你究竟观察了多少设备?问题是,它严重依赖于设备的磁盘速度,以及设备同时执行的其他 IO 操作。因此,仅仅观察你的电脑,尤其是性能良好的电脑,并不能提供非常多样化的测试。

      测量 localStorage 和 IDB 的性能非常困难。由于 localStorage 是同步的,浏览器试图通过预加载数据来解决它的阻塞行为。因此,仅仅在读取 localStorage 的循环中添加 Date.now() 调用实际上并不能测量实际的 IO。

      但我完全同意 IDB 还没有成为一个好的替代方案,因为它还没有得到广泛的实现。Firefox、Chrome 和 IE10 支持它。Opera 正在开发一个实现,但目前还没有关于 Apple 是否会为 Safari 实现它的消息。

      对于移动设备,Firefox 移动版肯定支持它。我认为 Android 版 Chrome 也支持,我希望 Windows Mobile 很快就会支持它。

      但再次强调,谁知道 Apple 和 iOS 会怎样。Apple notoriously 沉默寡言,但我怀疑他们不想在所有其他浏览器都实现 IDB 后落后。

      2012 年 3 月 5 日 下午 11:30

      1. Ian Bicking

        也许更现实的看法是将 localStorage 看作是内存中数据结构的 API,异步的“真实”持久化(即磁盘访问)在后台进行。根据你的描述,这基本上就是它的实现方式。内存访问实际上不会阻塞,而且由于配额很低,访问可能不会超过内存中可以合理存储的范围。因此,从很多方面来看,当前的状态似乎是合理的。此外,在 web 环境中,数据持久化的异步性质也是合理的,因为永远无法保证任何东西会原子地写入,或者不会被丢弃。

        如果你开始丰富 localStorage API(例如提供增加配额的好方法),那么它似乎很可能会开始导致一些目前看起来很理论性的问题。

        2012 年 3 月 5 日 下午 12:06

      2. Jens Arps

        是的,我使用过不少移动设备,包括一些非常差的设备,从糟糕的硬件原型到非常便宜的安卓手机。我在这些设备上大量使用 ls,没有遇到任何问题。

        关于性能测量:它并不难。如果你愿意查看测试,你会发现它是读写结合,并且使用随机数据。因此,我认为结果是可靠的。

        说真的,我只想知道为什么我应该停止提倡使用 ls。通常提出的反对 ls 的主要问题,实际上并不适用,至少对于 ls 如今的用途来说并不适用。

        2012 年 3 月 6 日 上午 2:00

        1. Jonas Sicking

          正如我所说,加载数据并不总是发生在你实际使用 API 的时候。

          在一个良好的 localStorage 实现中,数据在第一次访问后会保留在内存中,因此性能损失实际上只发生在第一次访问,之后就不会再发生,直到用户重新加载页面。

          如果你查看你链接的测试,它们在实际测量的循环之外第一次访问 localStorage。因此,他们实际上并没有测量 localStorage 最重要的部分。

          至于 IndexedDB 的测量,他们犯的第一个错误是在进行读取之前等待写入的成功回调。这意味着网页只是在那里等待,测试的大部分时间都是无意义的等待(IndexedDB 允许你在写入后立即调度读取,你将获得正确的数据)。

          同样,如果你想从 IndexedDB 中读取 1000 个值,你不会读取一个值,等待它返回,然后读取下一个值。然而,测试似乎就是这么做的。你真正应该做的是进行 1000 次 .get 调用,然后等待所有结果返回。

          第二个问题是,由于 IndexedDB 是一个异步 API,你不能简单地在前后添加 Date.now(),并试图用这种方法来测量吞吐量。由于 IndexedDB 是异步的,这意味着你的页面可以自由地执行其他处理,响应用户交互等等,而加载正在进行。测试中完全没有考虑这一点。

          正如我所说,测试 IndexedDB 和 localStorage 的性能很困难。

          当然,另一个问题是我们还没有开始关注 IndexedDB 的性能,但我们已经花了相当长的时间来优化 localStorage 了。

          2012 年 3 月 6 日 上午 3:33

          1. Jens Arps

            感谢你花时间查看测试!

            你的所有观点都有效。我并没有计划进行那么详细的测试,但如果有人想做,那么你说的没错,测试确实很难。在一定程度上,甚至可能是不公平的。我无法想到如何设计一个足够精确和公平的测试,但也许这并不必要,因为 IDB 规范可能会发生变化,实现还远未优化。

            我完全理解在 ls 访问之前(“最重要的是”)发生的磁盘 I/O 阻塞问题,但我认为“性能糟糕”的说法有点难以让人信服。也许我只是幸运,在工作中没有遇到磁盘 I/O 问题。

            正如标题所说,没有简单的解决方案。但是,当我必须在通过可能糟糕且昂贵的网络获取 JS 文件和从 ls 获取文件之间做出选择时,我宁愿冒着阻塞浏览器几毫秒的风险;我认为这是一个合理的决定(至少在我们有其他选择之前)。当我必须存储 1k 的应用程序设置时,我也会冒着阻塞的风险,这样可以省去我加载 IDB 或 Sqlite 代码,或者使用 cookie 来消耗带宽。

            当 IDB 最终出现时,我会毫不犹豫地支持你,并推动迁移。

            2012 年 3 月 6 日 上午 4:58

  10. Benedikt P. [:Mic]

    非主题建议

    使用“Summary:”之类的词语代替那个(在我看来)糟糕的“TL;DR:”怎么样?

    2012 年 3 月 5 日 下午 5:40

    1. Chris Heilmann

      Totes

      2012 年 3 月 5 日 下午 5:44

  11. check_ca

    HTML5 文件写入 API 不是另一种选择吗?我天真地以为它被设计用来存储文件...

    http://www.w3.org/TR/file-writer-api/

    2012 年 3 月 5 日 上午 8:26

    1. Jonas Sicking

      FileWriter 的跨浏览器支持比 IDB 更差。目前它 *只* 在 Chrome 中实现。在最近的 TPAC 会议上,所有其他浏览器供应商都表示他们没有计划实现它。

      2012 年 3 月 5 日 下午 11:48

      1. check_ca

        感谢你的回复。我不知道其他浏览器供应商的立场。然而,我不认为 FileWriter API 不是一种可能的 *未来* 替代方案(它在 Chrome 上已经运行了好几个月)。

        2012 年 3 月 5 日 下午 1:08

      2. A.J.

        google: FileWriter, etc
        mozilla: DeviceStorageAPI
        microsoft: WinRT

        我奇怪为什么没有一个统一的解决方案,但我非常确定这不是技术问题。可能是存在某种战略性的暗示,浪费我的时间?之前也发生过这样的事,我不喜欢它。

        2012 年 3 月 5 日 下午 3:34

        1. Jonas Sicking

          DeviceStorage API 旨在用于与“FileWriter, etc”截然不同的用例。

          我认为你说的“etc”是指 FileSystem API 的其余部分吗?

          如果是这样,FileSystem API 的用例主要是能够简单地存储文件。即类似于 IndexedDB 和 localStorage,但专门针对一种“数据类型”,即文件。

          我个人认为 IndexedDB 是一个更好的解决方案。从 Firefox 11 开始,我们将支持在 IndexedDB 中存储 File 和 Blob 对象,就像其他任何数据类型一样。也就是说,你不需要使用一个 API 来存储字符串、数字、JSON 对象,而另一个 API 来存储文件。你可以使用同一个 API 来存储所有数据。

          DeviceStorage API 旨在安全地访问“图片”和“文档”文件夹。这是 FileSystem/FileWriter API 做不到的。

          2012 年 3 月 6 日 上午 3:04

  12. Rakesh Pai

    为了说明问题,如果没有 localStorage,另一种选择就是从服务器上通过网络加载数据。毫无疑问,这要慢得多。我们通过使用磁盘而不是网络,消除了这种性能开销。

    此外,提到的优化,即浏览器将数据保存在内存中,应该会将查找时间再次提高几个数量级。内存占用过高也是一个真正的问题,但显然它被限制在最大 5mb。当然,在内存中会消耗比 5mb 多一点,但不会多出太多。

    因此,性能并不是什么大问题(磁盘与网络、内存与磁盘、内存与网络),同步 API 也不是什么大问题(反正也是从内存中加载)。所以,唯一真正的问题是存在 5mb 的限制。

    或者我漏掉了什么吗?

    2012 年 3 月 5 日 上午 8:51

    1. Jonas Sicking

      FileWriter 的跨浏览器支持比 IDB 更差。目前它 *只* 在 Chrome 中实现。在最近的 TPAC 会议上,所有其他浏览器供应商都表示他们没有计划实现它。

      2012 年 3 月 5 日 下午 11:33

      1. Jonas Sicking

        嗯... 不知道为什么会这样,之前的回复是针对另一条评论的。

        无论如何。

        访问网络几乎总是比访问磁盘慢。

        问题是同步 API。它并不总是从内存中加载数据。我们负担不起将所有 localStorage 数据加载到内存中,因为数据量可能很大。相反,我们所做的是尝试预测网站何时会使用 localStorage,并在那时将数据加载到内存中。

        但预测并不总是奏效。有时在我们将数据加载到内存之前,会发生获取 localStorage 数据的请求。由于 API 是同步的,这意味着页面会被阻塞,直到我们加载完数据。

        因此,虽然访问网络更慢,但它不会导致页面被阻塞(除非你使用同步 XHR,但出于同样的原因,你不应该这样做)。

        我当然不是说将数据存储在服务器上总是比使用 localStorage 更好。但我只是想回答你在评论中提出的一些问题。

        2012 年 3 月 5 日 下午 11:47

        1. Sean Hogan

          如果一个网站使用 LocalStorage 来保存设置(基本上是 cookie 的替代品)而不是保存文件,那么性能应该不会成为问题吗?

          2012 年 3 月 5 日 下午 3:10

          1. Jonas Sicking

            这意味着我们将不得不加载更少的数据,这当然会使第一次访问更快。但它仍然需要同步加载,这意味着如果磁盘正在忙于执行其他操作,我们将不得不等待磁盘完成其操作才能取消阻止页面。

            2012 年 3 月 6 日 上午 1:58

        2. Rakesh Pai

          感谢您的回复,Jonas。

          预测网站是否需要 localStorage 的技术似乎是个好主意。浏览器决定页面是否需要 localStorage(再次,本地查找或类似内容)以及将数据加载到内存中,与网站开始使用它(通常涉及通过网络加载脚本)之间的竞争条件,应该不会造成太多性能问题,我想。我当然可能错了,但它确实似乎有改进的空间。

          可能有一些想法可以从内存数据库中获取,这些数据库会延迟持久化到磁盘,比如 MongoDB。

          我想说的是,现在的 API 很棒,而且非常容易使用。如果浏览器可以进行繁重的操作以确保 API 至少在大多数情况下运行足够快,我们做得很好,不是吗?

          2012 年 3 月 5 日 下午 8:17

          1. Jonas Sicking

            我个人没有数字,但你真的想要一个只在“大多数情况下”工作的 API 吗?

            我认为大多数用户希望得到可靠的东西,所以最终这也是我希望开发人员也希望得到的。

            2012 年 3 月 6 日 上午 2:05

  13. Charles

    如何压缩 localStorage,也许可以为此提供一个 API 来
    a) 允许在 localStorage 中存储更多内容
    b) 实际上加快速度。如果 CPU 比磁盘 I/O 快得多,就会发生这种情况

    此外,使用访问权限来清理 localStorage。

    2012 年 3 月 5 日 上午 9:05

  14. JulienW

    我也担心安全性,因为同一来源(即:方案/主机名/端口)上的每个页面都可以使用 localStorage 中的相同数据。

    也许现在这不太重要了,因为几乎每个人都有自己的域名,但我认为在一些共享的网络托管服务中这仍然是一个问题。

    2012 年 3 月 5 日 上午 9:26

    1. Jonas Sicking

      所有具有相同来源的页面都可以始终读取彼此的数据。如果您打开一个指向同一来源的另一个页面的页面,您可以进入该页面并访问它创建的 DOM 或 JS 对象的任何部分。

      实际上,网络的安全模型是每个来源都是它自己的安全域。不幸的是,现在已经太迟了,无法尝试创建比这更细粒度的任何东西。

      2012 年 3 月 6 日 上午 2:08

      1. Jonas Sicking

        哎呀,那应该是

        如果您打开一个指向另一个页面的 *iframe*…

        2012 年 3 月 6 日 上午 3:47

      2. JulienW

        实际上,您所说的“网络的安全模型”并不那么普遍。

        实际上有一个非常著名的例外:cookie。cookie 的安全模型包含域(顺便说一句,可以是网页域的任何父域)和路径。我真的想知道为什么没有将其用于其他安全模型。

        也许现在已经太迟了;那么必须了解它,以便应用程序保持安全。

        2012 年 3 月 15 日 上午 3:04

    2. Nealle

      安全也是我关心的问题,我为一家大型金融机构工作,我们正在为开发人员编写指南,供他们在开始 HTML5 开发时使用,重点关注移动设备,而现在尽管存在所有上述问题,我们仍将简单地禁止离线存储,因为我们无法将内容加密到足以让我们确信在设备被盗或丢失的情况下数据是安全的程度。

      2012 年 3 月 14 日 下午 2:00

  15. Kevin

    感谢您发布此警告。您是否有任何关于实际性能统计数据的资料?看起来相对于任何网络调用,localStorage 仍然可能非常快……只是当您期望它以同步方式透明地工作时,它才很差。也许结合 Web Worker 或其他异步执行此操作的方式,它仍然可以提供比从网络加载快得多的速度。

    2012 年 3 月 5 日 上午 9:31

  16. Andy Fuchs

    我完全同意 Jens 的观点。当我们不得不与 cookie 作斗争时,LocalStorage 真是个救星。
    主要优势是,它今天就在这里,并且在所有现代浏览器(移动或非移动)上都能正常工作。
    对于关注移动用户的人们(而且他们越来越多),它是唯一安全的存储选项。其他一切都很有限。
    由于大多数移动设备上都使用 webkit,并且支持与桌面相同的通用 API,所以我最近放弃了 Firefox 很多次。
    从开发人员的角度来看,我们必须停止单一浏览器供应商(先是 IE,然后是 MOZ,现在是 Webkit)的命令,来扼杀通用且可用的 API,这是不可避免的。
    这将使网络对我们所有人来说都更易用!

    2012 年 3 月 5 日 上午 9:41

  17. Larry Garfield

    您真的需要在上下文中查看这些问题。是的,同步 API 会阻塞,但这仍然会比网络往返更好吗?有时,是的。如果您只存储少量的小数据(而不是几兆字节),那么内存开销将很小。

    “将 localStorage 规范更改为异步存储而不是同步存储?我们还可以扩展它以拥有一个适当的 getStorageSpace 接口并允许原生 JSON 支持”

    这听起来确实是最合适的选项。localStorage 具有最易用的 API 的优势。所以修复它。添加一个异步选项(XHR 同时具有同步和异步选项,请回忆一下),根据需要添加一些其他方法,我们就完成了。这只需要 W3C 和浏览器供应商同意这样做,我们就可以完成了。

    …好吧,也许这需要一段时间。:-)

    2012 年 3 月 5 日 上午 9:55

  18. Steve Souders

    我认为问题在于浏览器磁盘缓存没有提供必要的性能和功能。研究表明,普通用户的缓存“命中率”低于我们的预期。清除算法尚未开发(例如,基于内容类型的优先级排序)。没有保证每个网站的空间。而且没有 API。

    我呼吁浏览器专注于磁盘缓存已经两年了(http://www.stevesouders.com/blog/2010/04/26/call-to-improve-browser-caching/)。当时,我警告说 localStorage 被错误地用作磁盘缓存的替代品(FB 已经在这样做)。我们在磁盘缓存方面取得了一些很好的改进——主要是大小——但我们远未达到应有的水平。马已经离开了马厩。试图通过宣传人们放弃 localStorage 来解决这个问题不会成功。

    LocalStorage 将继续存在。最好的解决方案是浏览器供应商解决这些问题。(抱歉——我知道这意味着您需要做更多工作。我希望我们能在 localStorage 变得流行之前修复磁盘缓存!)浏览器应该做什么?

    1. 添加回调功能——领先的专家会明智地使用它,但我们必须认识到,大多数网站在几年内都不会采用这种新的模式。

    2. 更好的 UI——用户很难弄清楚如何查看、编辑、清除和限制他们的 localStorage。需要一个更好的 UI。

    3. LRU 清除——如果 localStorage 被广泛使用,那么每个网站 5MB 可能占用户磁盘空间的很大一部分。浏览器应该将最近使用信息添加到 localStorage,以便可以回收未使用的网站的字节。

    4. 预加载——使用此 LRU 数据,浏览器可以更智能地确定是否在请求网站 URL 时立即将字符串从 localStorage 读取到内存中(以期获得该 HTML 文档响应调用 getItem)。这允许各种内存使用优化,例如,如果一个键长时间没有被访问,就不应该预加载它。

    我相信浏览器团队可以想到其他改进,也许已经实现了。我的主要观点是,摆脱困境的最佳方法是浏览器团队(再次)站出来,以便 Web 开发人员可以专注于他们的应用程序,而不是专注于已经添加到浏览器的功能的性能。

    2012 年 3 月 5 日 下午 10:58

    1. Taras Glek

      Steve,我们已经开始解决缓存问题
      * Firefox 缓存现在可以达到 1gb(事实证明,这在一些机器上太多了)。

      * 还有很多工作要做。自从浏览器缓存首次引入以来,一些基本假设发生了变化(即硬盘驱动器不再严格地比网络快),并且缓存项目的尺寸已迅速增长。

      * 像 html5 视频这样的东西需要缓存来缓存要稀疏存储的项目(即,当您在视频下载时在视频中四处查找时)。

      我认为浏览器缓存中有很多优化空间……而且鉴于 Local Storage 的许多用例似乎是为了避免处理浏览器缓存,也许浏览器提供的更好的缓存控制将解决一些 LS 问题。

      2012 年 3 月 5 日 下午 12:12

      1. Larry Garfield

        改进的浏览器缓存将非常受欢迎,这样我们就不用想出像这样的疯狂主意:http://www.garfieldtech.com/blog/caching-tng

        :-)

        2012 年 3 月 5 日 下午 12:19

        1. Taras Glek

          Larry,
          太棒了。我试图总结 LS->Cache 的想法:


          http://groups.google.com/group/mozilla.dev.tech.network/browse_thread/thread/4acf1c6e5b071193#

          我注意到,大多数 LS 使用都是为了绕过缓存……因此,设计一个全新的子系统而不是让缓存更有用是有意义的。感谢您提出这个想法!

          2012 年 3 月 5 日 下午 1:20

  19. staras

    在 2010 年 1 月 6 日,我们阅读了 Arun Ranganathan 和 Shawn Wilsher 撰写的文章:Firefox 4:对 I 的早期概述。今天,在一年半后,我们再次阅读一篇关于 indexedDB 的文章,文章称这是 Web 存储的未来。indexedDB 的进展在哪里?
    为什么要停止使用 WebSql?
    为什么要停止使用 localstorage?
    没有逻辑。
    请支持现有的简单实现。

    2012 年 3 月 5 日 上午 11:31

  20. Jonas Sicking

    我很想看到一个类似 localStorage 的更简单 API 的提案,但它仍然是类似 IndexedDB 的异步的。不必是 W3C 起草草案。如果有人起草了似乎能让开发人员感到兴奋的东西,请不要犹豫,把它发给我,我会帮助将其推送到 Web 浏览器。

    甚至可以很容易地将这样一个 API 的实现编写为一个由 IndexedDB/WebSQL 支持的 JS 库。

    设计这样一个 API 的方法有很多,所以与其说是我们能不能做到,不如说是我们希望这样一个 API 拥有哪些功能。

    一个解决方案可能类似于

    getBetterLocalStorage(function(storage) {
    x = storage.foo;
    storage.bar = calculateStuff(y);
    storage.baz++;
    });

    这个 API 非常简单,但需要实现将所有数据加载到内存中,然后才能调用回调函数。也就是说,如果您想在其中存储大量数据,此 API 无法很好地扩展。但它对于少量数据效果很好。

    另一个可能的 API 是

    betterLocalStorage.get(“foo”, function(x) {
    doStuffWith(x);
    betterLocalStorage.set(“foo”, x+1);
    });

    这种 API 的缺点是,很容易在代码中意外地出现竞态条件。或者更确切地说,是不可能避免的。如果你想将 "foo" 键的值增加 1,你首先需要使用异步调用读取数据,然后在另一个调用中设置它。但是,没有任何东西可以保证该值不会在两者之间发生变化,例如,由于同一个页面在另一个选项卡中打开。

    所以另一个解决方案是
    lock = betterLocalStorage.getLock();
    lock.get(“foo”, function(x) {
    doStuffWith(x);
    lock.set(“foo”, x+1);
    }

    那么问题是,我们希望新的 API 具备哪些功能?为了获得能够扩展到大量数据、没有竞态条件或解决各种用例的东西,我们愿意在 API 中承受多少复杂性?

    IndexedDB 绝对处于范围的复杂端。它支持许多用例,并且应该能够很好地扩展,但结果比上面所有的 API 都要复杂。

    值得一提的是,上面所有的 API 都可以用几行 JavaScript 使用 IndexedDB(以及根据你想要的数据类型,使用 WebSQL)进行原型设计。

    2012 年 3 月 5 日 下午 2:11

    1. Rakesh Pai

      如果我必须选择一个(我不喜欢改变我们已经拥有的东西),我会选择你的第二个例子。这主要是因为它很简单,易于使用。此外,它可以与现有代码向后兼容。如果开发人员想要易用性,就使用当前的样式。如果数据变得太大,磁盘 I/O 似乎成为了瓶颈,则提供回调以使其异步。API 实现只需检查是否传递了回调,并据此决定它是否应该是异步的。

      竞态条件问题可能不是那么大。例如,我们没有看到人们抱怨 Ajax 的竞态条件问题。当然,它可能会让人们感到困惑,但对大多数人来说,这不是一个巨大的学习曲线。我猜想,当然。

      当然,我仍然坚持 API 不应该改变我们现在拥有的东西。我非常确定浏览器可以做更多的事情,使当前 API 的性能开销可以忽略不计。

      2012 年 3 月 6 日 下午 8:31

    2. Ian Bicking

      为了处理锁定,也许

      betterStorage.get(“key”, function (x) {
      betterStorage.set(“key”, x+1, x, function (succeeded) {
      // 如果 succeeded 为 false,则 key == x 的前提条件失败
      });
      });

      这使得对竞态条件的忽略访问变得相当容易(省略前提条件),并且仍然允许进行谨慎的编程,但避免了死锁。localStorage 不是特别可靠,因此,很少有人担心缺乏处理竞态条件的方法并不奇怪 - 这不是人们保存关键数据的地方。添加锁可以帮助数据完整性,但会引入其他可能使页面停滞的编程错误(或者至少会导致回调永远不会被调用等)。我认为这对这种类型的 API 来说是一个糟糕的妥协。

      2012 年 3 月 15 日 下午 1:15

  21. Kim T

    前端开发人员真的没有必要创建和更新数据库,尤其是如果模式可能发生变化的话。

    为什么我们不能简单地在 JavaScript 中使用一个属性来定义变量为缓存

    cache var items = {};

    然后我们可以简单地使用以下方法覆盖这个对象
    items = {};

    或使用以下方法删除

    delete items;

    简单...

    2012 年 3 月 5 日 下午 4:15

    1. Chris Heilmann

      我真的很喜欢这个想法。可以有一个触发器来询问“你想要这个吗”,但这很有意义。

      2012 年 3 月 5 日 下午 4:27

      1. Rakesh Pai

        如果我理解正确的话,这并不能解决大多数问题。数据需要存储/检索到磁盘,这意味着我们需要它同步,或者我们需要一个基于回调的异步 API。此外,这会将所有数据保存在内存中,因此不能帮助减少内存占用。此外,没有描述控制数据增长的机制,所以我猜测 5MB 的限制也适用于这里,并且仍然需要基于权限(或其他)的机制来获取更多存储空间。

        或者,我遗漏了什么。:D Chris,我不确定你所说的“‘你想要这个’的触发器”是什么意思。

        PS:验证码真的很难!我刷新了 7 次才找到一个可读的。

        2012 年 3 月 5 日 下午 8:39

    2. Matthew Holloway

      那可能应该是同步的,并且会阻塞,对吧?我看不出它如何有回调,或者有 Promise 对象,来延迟访问数据。

      当浏览器看到一个缓存语句时,它是否必须在那个时候加载整个映射?可能很难使其足够细粒度以从键中惰性加载值。如果是这样,它就不能真正用于浏览器内的文件系统,这些文件系统可能需要能够存储数百兆字节的数据。

      你将如何取消缓存?你有一个将缓存设置为空的示例,但它可能仍然会保留空映射的值。

      2012 年 3 月 5 日 下午 8:20

    3. Jonas Sicking

      这基本上与 localStorage API 完全一样。因此它将具有完全相同的问题。

      要解决 localStorage 的问题,我们确实需要一个异步的东西。

      2012 年 3 月 6 日 上午 1:55

  22. forrestliu

    也许异步文件 API 更合适。

    2012 年 3 月 5 日 下午 6:17

  23. Henri Sivonen

    问题列表中缺少最著名的 localStorage 问题:在多个事件循环浏览器(例如 IE 和 Chrome)中,localStorage 的实现要么必须向 Web 内容公开竞态条件,要么使用对性能非常不利的跨进程锁。

    2012 年 3 月 6 日 上午 12:41

  24. Andy Walpole

    为什么选择 IndexedDB 或 WebSQL?为什么浏览器不能同时支持两者?

    2012 年 3 月 6 日 上午 1:46

    1. John Thomas

      这并非没有先例,毕竟,曾经浏览器将 innerHTML 和 DOM 支持视为竞争规范,但最终决定同时支持两者。此外,它可以简单地设计为:这里有一个低级 API,这里有一个高级 API。第三,即使 Mozilla 只想实现一个兼容性层,如果该层在浏览器内,你可以利用用于 SQLite 的 SQL 解析器,我认为这将为你提供更好的性能(是的,每个人都说 JavaScript 的性能接近原生性能,也许如果 JavaScript 是为高性能而编写的,而原生代码不是,但即使那样,我还没有看到这种情况发生)。

      2012 年 3 月 6 日 上午 11:35

      1. Shawn Wilsher

        Mozilla 在内部使用比 WebSQL 规范要求更新的 SQLite 版本,因此他们不能只使用他们已经提供的 SQLite 解析器。

        2012 年 3 月 8 日 上午 11:53

  25. John Thomas

    关于 WebSQL 规范是一个糟糕的规范的想法:说得对,但如果那是 Mozilla 对 WebSQL 的问题,有一个非常简单直白的方法来解决它 - 根据 SQLite 的规范编写一个 SQL 支持规范。

    更大的问题是,有一个好主意(Web SQL 数据库的一般概念,而不是特定的规范)正在获得动力,而 Mozilla 扼杀了这种动力,现在我们必须等待几年,才能让 Mozilla 说服所有其他浏览器制造商采用它的标准,我们需要等待更多测试实现和意外问题(同样,因为你正在设计一个新的 API,你会遇到人们将它用于奇怪的用途,并且需要根据这些用例进行调整,而对于基于 SQL 的 API,你可以将 SQL 使用的历史模式作为潜在问题的警告),然后我们才能拥有跨浏览器解决方案的 Web 数据库。

    关于你可以在 IndexDB 之上构建一个 SQL 兼容性层的说法,是的,但是 JavaScript 必须实现 SQL 解析器和映射器以进行 IndexDB 操作(尤其是如果你想添加对带有函数的查询的支持),我怀疑 SQL 兼容性层在性能上是否合理。

    然后,开发人员不得不使用另一个 API,另一组最佳实践(即使使用一个简单的 API,最佳实践也可能是一个杀手,jQuery 的选择器语法非常简单,但当你开始担心性能和选择器优化时,事情就开始变得更加复杂)。根据我的经验,我会说至少 3/4 的前端 Web 开发人员都有一些后端经验和一些 SQL 的接触,如果 HTML5 存储使用这种方法,那么它会更容易使用。

    2012 年 3 月 6 日 上午 11:28

    1. Shawn Wilsher

      你的历史是错误的。IndexedDB 规范最初来自 Oracle,Google、Microsoft 和 Mozilla 都非常喜欢它,并加入了标准化工作。

      2012 年 3 月 8 日 上午 11:52

  26. John Thomas

    现在我已经对 WebSQL 大肆抱怨了一番,让我退一步说,对不起,如果我过于严厉,Web 技术的世界正在稳步远离我对它的愿景,但这是我的问题,而不是 Mozilla 的问题。随着我的幻灭感越来越强,我可能会转向做更多的原生编程,并且会因此而变得更好。

    但这里有一个 HTML 应用程序存储的根本问题:用户需要完全控制他们的存储选项(在管理存储选项时尽可能减少麻烦),而应用程序依赖于持久存储,好吧,持久性。这将是任何存储 API 的一个复杂因素,需要首先明智地解决(即使我们只谈论 cookie 存储)。

    如果我是一个制定规范的人,而我并不是,我可能会编写一个包含保存 Web 数据的 API 的规范。也就是说,网站可以触发一个提示(您是否希望保存本次会话的数据?)。此外,当你清除 cookie 时(这应该清除所有持久数据,因为用户只习惯将 cookie 作为持久数据的一种形式,并且不应忽略他们想清除的东西),也许用户会收到一个提示(并可以选择永不再显示),“您有 X 个 Web 应用程序在您的浏览器中保存了信息,您是否想删除它们?” -> 用户还应该收到一个触发器,用于逐个应用程序编辑要保存的应用程序和要放弃的应用程序。

    除此之外,用户应该在任何时候都有选择“导出”其特定 Web 应用程序的数据并将其重新加载到另一个应用程序中的选项。这是大多数存储方法都无法满足的一点,虽然一些同步服务提供例如 Cookie 数据的同步,

    A. 它们通常不提供对非 Cookie 存储的完全同步
    B. 如果它们提供,通常是特定于浏览器的
    C. 至少我个人喜欢为我的导出文件,特别是由于我喜欢摆弄这些文件。

    如果有一个 API 可以提供给插件来利用它进行数据存储,那将非常不错(我意识到浏览器供应商可能不关心这一点,因为他们试图杀死插件(而没有在扩展程序中提供类似或接近类似的功能,这是 Mozilla 闪耀的一个方面)),但如果一个 API 被提供给插件来利用它进行数据存储,那将非常不错(如果可以触发一个选项,只使用那些使用 API 进行持久数据存储的插件(即,它们仍然可以将数据保存到 %TEMP% 以用于缓存数据,或保存到此 API,但不能保存到底层文件系统),对于所有插件可能行不通,所以我真的希望它是一个提供给用户的开关(在选项菜单中,所有选项都应该可以通过选项菜单“about:config”以某种方式访问)))。

    2012 年 3 月 6 日 下午 11:54

    1. John Thomas

      我意识到我发布了很多内容(而且我的午休时间差不多结束了,所以我正式地偷懒了),但是如果可以简单地有一个存储网页状态的选项呢?这并不完全解决用户对可擦除存储与持久存储需求的困境,但即使有一个完整的 JS 数据库 API,无论是 WebSQL 还是 IndexedDB,开发人员最终都会在 DOM 中以属性和隐藏元素的形式存储大量数据。如果他们想让这些数据持久化,他们就需要提取并序列化这些数据,即使有一个功能齐全的持久存储 API(如今,大多数开发人员会序列化数据并将其发布到服务器,数据在那里以会话数据形式存在)。

      但是如果他们可以直接在浏览器中保存网页的当前状态,然后网站可以要求说,恢复命名的会话(例如,可以有一个输入类型会话)。

      这并不完全是持久存储 API 的替代品(毕竟你可能有一个巨大的页面,而只有少量持久数据),但至少它很酷。

      2012 年 3 月 6 日 下午 12:05

  27. Kim T

    如果类似于
    cache var item = {}

    没有奏效,那么我认为下一个最好的选择是一个 JSON feed 保存选项
    window.store(feed, ‘data.json’);

    然后我们也可以将对象保存到磁盘,并在之后以与创建或加载时相同的格式加载它们。

    2012 年 3 月 6 日 下午 13:18

    1. Jonas Sicking

      就像我上面说的,如果人们能够就一个他们希望浏览器实现的*异步* API 达成一致,那将是巨大的第一步。

      我上面甚至提供了三个关于这种 API 可能是什么样子的示例。

      每个人都有不同的用例,所以找到一个适合所有人的解决方案并不容易。

      2012 年 3 月 6 日 下午 14:59

  28. greg

    Android、iOS、Symbian 都使用 SQLite,应用程序开发人员对此很满意。SQL 太复杂了吗?但是 JavaScript 和 CSS 定位不复杂吗?

    当然,继续寻找你自己的 WinFS。

    2012 年 3 月 6 日 下午 16:22

    1. Robert Nyman

      我相信 WebSQL 的缺点在上面的评论中已经涵盖了,包括具体版本和其他问题。

      2012 年 3 月 7 日 上午 01:31

      1. Pete

        我仍然试图找出为什么 Mozilla 的家伙们如此反对 WebSQL,却没有任何合理的论据。

        上面也提到,目前 WebSQL 几乎涵盖了所有移动设备,而且所有人都很满意。

        2012 年 3 月 7 日 上午 02:04

        1. Jonas Sicking

          我们不喜欢 WebSQL 有很多原因。

          1. 没有两个 SQL 引擎实现相同的 SQL 方言。你最基本的“Select * from table”查询可以在任何地方运行,但很快就会开始表现得略有不同。因此,除非所有浏览器都同意使用同一个 SQL 引擎后端(并且同意永远这样做,即使创建了其他更快的数据库引擎),否则不同的浏览器将执行不同的操作。这对网络来说并不好。

          2. 同一个 SQL 引擎的不同版本之间经常存在 SQL 方言的细微差异。正如大多数服务器开发人员所知,在将 SQL 引擎升级到新的主要版本时,你通常需要对查询进行一些小的更改。在服务器上这很好,因为你可以控制何时更新 SQL 引擎。在网络上则不行,因为你不知道用户什么时候会更新他们的浏览器,以及不同的用户使用什么版本的浏览器。浏览器将被迫升级他们的 SQL 引擎,因为旧版本不再受支持,并且存在已知的安全问题。此外,我们希望能够使用最新版本以提高性能。

          3. 即使对于 SQL 引擎给出相同结果的 SQL 查询,性能也可能大不相同。如果 SQL 引擎没有意识到应该使用特定的索引,它可能会很容易地慢 1000 倍,即使对于中等规模的数据集也是如此。你真的可以接受你网站上的某些函数在特定浏览器中运行速度慢 1000 倍吗?这在服务器环境中不是什么大问题,因为你可以测试你的查询,以确保它们能够与你打算使用的 SQL 引擎一起运行,但在网络上则不行,因为我们希望 API 在不同浏览器之间能够一致地运行。

          4. SQL 中的性能是出了名的难。缺少索引可能意味着你的查询会挂起,执行时间会延长到几分之一秒。让性能变得困难的一件事是,你实际上并没有表达你想要 SQL 引擎做什么。你表达了你想要的结果的一些约束条件,并希望引擎足够智能,可以使用实际上很快的完全不同的执行策略。任何处理过复杂的性能关键查询的 SQL 开发人员都曾坐在那里调整他们的查询,在实际上含义相同的不同表达式之间进行切换,直到 SQL 引擎突然“明白”了,并使用了你想要的索引。另一个问题是,如果你遇到了性能问题,问题可能不是在性能慢的代码部分,而是你在构建表格时,列的顺序错了,或者索引集错了。

          5. SQL 并不是特别“Web 式”。也就是说,你无法直接存储你的 JSON 对象。相反,你必须手动将数据拆开,然后将其放入列中。当然,你可以使用 JSON.stringify,但这样你就无法对对象中的任何数据进行索引。

          6. SQL 注入攻击。它们发生在*任何地方*,人们使用 SQL 结合不可信数据的地方。即使有 API 功能可以帮助你避免这种情况。连接字符串实在是太容易了,以至于人们不断地陷入这个陷阱。

          2012 年 3 月 7 日 下午 20:12

          1. greg

            1. 只需使用 SQLite。 “因此,除非所有浏览器都同意使用同一个 SQL 引擎后端”——所以问题是政治性的。HTML/CSS 实现之间也存在细微的差异。为了保持一致性,你也应该停止支持这些规范。

            2. 谢天谢地,你不属于 IE 团队,我们不必再忍受 IE6 的错误了。顺便说一句,SQLite 足够小,所以可以在一个浏览器中保留几个版本。

            3. 这是在开玩笑吗?数百万开发人员已经在 IE、FF、Chrome 和 Safari 中测试了 Web 应用程序。

            4. 真是太棒了!从 JavaScript 中删除循环和数组。你知道在 O(n) 时间内排序数字有多难吗?只要向数组中添加太多数字,用冒泡排序进行排序,你的浏览器就会卡住!

            5. 那么 localStorage 可以根据字段对对象进行索引吗?

            6. 好尝试。在客户端,你根本不必担心 SQL 注入。提示:你需要在服务器端再次验证所有数据。

            2012 年 3 月 8 日 下午 12:26

  29. Lars Gunther

    还没有人提到这一点,但反对 WebSQL 的一个主要论据是,它不是默认情况下针对 SQL 注入安全的。

    考虑到有多少企业应用程序尽管由高薪且据说是知识渊博的程序员开发,却仍然容易受到 SQL 注入攻击,可以肯定地说,不安全的默认设置不是一件好事。

    附注:请停止使用 reCAPTCHA。它太荒谬地令人恼火了!

    2012 年 3 月 7 日 上午 07:38

    1. abc

      你真的担心客户端的 SQL 注入吗?为什么有人会费心进行这种攻击,当他可以很容易地更改存储中的数据时?

      2012 年 11 月 6 日 上午 05:45

  30. Alenas

    这是所有似乎无法用 HTML 修复的问题的另一个例子。Web 需要转向比 HTML/DOM/JavaScript 更好的技术……所有这些聪明的人都困在一个想法上,他们停止了创新。Web 需要彻底的改革……完全没有必要踢死马……

    2012 年 3 月 7 日 下午 21:03

  31. Pete

    针对 1-6:与其完全放弃,不如对规范进行一些微调,例如定义一组稳定的 SQL 命令。希望你同意 99% 的 SQL 程序员都使用相同的查询,包括一些 JOIN 操作。关于 SQL 注入,如果重新定义规范,只允许使用准备好的语句,那就很容易了。关于“这不是 Web 式的”,嗯……

    你也可以在 WebSQL 之上构建 IndexedDB。这样,开发人员就可以选择,甚至可以使用两种不同的方式访问同一个数据库。

    最后,IndexedDB 没有说服每个人的原因是,它远不如 WebSQL 强大,但同时又比简单的异步键值存储过于复杂。

    正如有人之前所说,有时改进和完善拥有动量的东西比造成碎片化要好。这就是我们现在所处的状态。现在,桌面端的 IndexedDB 覆盖率超过 90%,移动端的 WebSQL 覆盖率也超过 90%。

    我想既然 Mozilla 决定放弃 WebSQL,他们就没有胆量重新决定了。这很好,时间会告诉我们哪项技术会成功。

    不过有一个问题:添加一个异步选项怎么样?
    localStorage.setItem(“key1”, “value1”); —> localStorage.setItem(“key1”, “value1”, function(){…});

    a=localStorage.getItem(“key1”) —> localStorage.getItem(“key1”, function(a) {})
    并告诉开发人员这是更快的方法。就像 WebSQL 一样。与其引入新的东西,不如改进现有的东西……

    2012 年 3 月 8 日 上午 00:53

  32. regis

    嗨!
    我们对 localStorage 进行了大量的研究,我可以说性能很好。
    唯一需要时间的函数是 removeItem(仅限 Firefox),可以用 setItem(key, “”) 替换。
    localStorage 的真正限制在于容量(5M)
    W3 标准规定,当网站需要更多空间时,浏览器应该弹出一个对话框。只有 Opera 做到了这一点……

    2012 年 3 月 8 日 上午 06:29

  33. Red

    SQL 是一个 ISO 标准。与之相比,IndexedDB 就如同一个孩子们的玩具。Mozilla(标准倡导者)扼杀了 WebSQL,这非常令人难过。通过这一举措,我们将被困在 localStorage 中多年。

    2012 年 3 月 9 日 上午 07:21

    1. Shawn Wilsher

      给我看看一个实现了 ISO 标准全部内容的 SQL 引擎。

      2012 年 3 月 13 日 下午 23:31

      1. Red

        你不需要完全实现这个标准。简单的联接和分组,你拥有的就远不止 IndexedDB 了。

        浏览器中没有完全实现 html 或 css,也没有人希望它们被放弃。

        如今,我们到处都有 SQL 引擎:浏览器、手机、服务器等。事实上:像 Oracle 或 MS 这样的巨型数据库是少数,而 sqlite 提供了良好的 sql92 子集。

        2012 年 3 月 14 日 下午 11:26

        1. Pete

          完全正确。感谢 Mozilla,我们现在拥有

          – LocalStorage,它是非异步的,
          – IndexedDB,它对于简单的键值存储来说过于复杂,但与 WebSQL 相比又不够强大,以及
          – WebSQL,它不再是标准。

          现在我们要谈论添加第四个选项。

          现在加入 WebSQL 还不算太晚,至少可以让移动设备有一个共同的基础,但我担心 Mozilla 没有勇气重新决定。

          实际上,addons.mozilla.org 上曾经有一个 WebSQL 附加组件,但由于某种原因已被删除。我在这里找到的唯一一个反对 WebSQL 的真正论点来自 Jonas Sicking,他说“它不够 Web 化”。哎…

          2012 年 3 月 15 日 上午 1:55

  34. Nigel Kelly

    完全同意。LocalStorage 很糟糕。我之前为 Palm Pre 上的 webOS 开发了一款游戏,最初使用 LocalStorage 保存关卡。我收到很多用户的抱怨。我切换到 websql,再也没有出现问题。异步保证了 js 不会在没有你的数据的情况下自行运行。同步不能保证这一点,因此才会出现用户的抱怨。

    2012 年 3 月 14 日 上午 5:10

  35. richtaur

    基准测试在哪里?

    2012 年 3 月 14 日 上午 10:33

  36. steve

    “主要问题:性能糟糕”

    如果这是主要问题,那就编写更好的代码并修复它。是的,真的就这么简单。

    如果浏览器在首次访问网站时将所有 localStorage 加载到缓存中,那么就停止它。难怪你认为它很慢。一个主机可能拥有许多独立的 Web 应用程序,它们使用 localStorage,因此你不应该一次将所有内容加载到内存中。这只是常识。让开发人员决定加载任何数据的最佳时间,并处理他们自己的缓存。这就是我们正在做的,因为我们无法保证每个浏览器都会缓存 localStorage。所以对于那些缓存数据的浏览器来说,这只是浪费内存——再次停止这样做。

    底线——localStorage API 本身没有问题,只有它的实现方式有问题。

    2012 年 3 月 15 日 上午 5:26

  37. Gregor

    我在我的应用程序中大量使用 localStorage。它将用户的全部数据下载到 localStorage,只是文本数据,但对某些用户来说,仍然高达 2MB。

    问题
    我理解正确吗?整个 localStorage 在第一次访问后就会被加载到内存中,即使我只读取一个键?而且从磁盘读取 2MB 是导致 UI 阻塞的主要原因,导致后续读取/写入被阻塞?

    2012 年 3 月 19 日 上午 8:56

  38. Foo

    为什么不在 localStorage 中添加 getItemAsync,以及可选的 setItem 回调?

    localStorage.getItemAsync(key, callback);
    localStorage.setItem(key, data, optional_complete_callback);

    setItem 返回并立即生效,但只有在 optional_complete_callback 被调用时,数据才会持久地保存到磁盘上。

    另一方面,getItemAsync 不返回任何内容,而是将数据传递给回调函数。

    2012 年 3 月 19 日 上午 11:07

  39. Dannii

    没有人提到的一个问题是,localStorage 和 IndexedDB 都不适用于 file: 方案(跨浏览器)。

    2012 年 3 月 19 日 下午 10:53

  40. Red

    我猜得对吗?localStorage 中邪恶的根源是数组操作符的使用?如果是这样,你能将其标记为已弃用吗?我在 Web 存储规范中没有找到任何关于它的说明…

    getitem/setItem 方法中没有任何内容需要将整个数据库加载到内存中…

    你也可以在 getItem 中添加可选的回调参数。

    第二个问题是 WebSql。杀死它无济于事。关于不完整实现的论点非常无效,尤其是在浏览器之间没有 HTML/CSS/JavaScript 共识的世界中。

    更糟糕的是。这是一个非常短视的做法。目前 JavaScript 不仅仅是浏览器,服务器开发人员别无选择——尝试使用除了 SQL 之外的任何东西,你可能会被嘲笑。

    我不明白为什么 Mozilla 在 SQLite 上遇到了很多问题。同一个引擎在其他浏览器、手机和许多其他设备中都可以正常工作。

    2012 年 3 月 20 日 上午 3:34

  41. Parashuram

    你也可以在 WebSql 上使用 IndexedDB polyfill——这样我们只需要处理 IndexedDB API,它可以在支持 IndexedDB 或 WebSQL 的浏览器上运行(大多数浏览器!)。

    polyfill 在这里——http://nparashuram.com/IndexedDBShim

    2012 年 6 月 7 日 上午 12:27

  42. Marcello Nuccio

    我使用 applicationCache + indexedDB 来构建离线应用程序。IndexedDB 使得可以在离线时存储用户输入。这很棒,但我担心这些数据的持久性。我发现,在 Chrome 中,持久性存储“只对使用文件系统 API 的应用程序可用”[1]。Firefox 使用什么策略?我在任何文档中都找不到。

    [1]: https://developers.google.com/chrome/whitepapers/storage

    2012 年 6 月 19 日 下午 11:22

    1. Taras Glek

      我们有一个 indexeddb 提示,一旦用户接受提示,数据就会永久保存。
      我们计划添加类似 Chrome 的无提示操作,它会自动清除数据,但我们仍然会允许提示来持久保存数据。

      2012 年 6 月 20 日 上午 11:37

      1. Marcello Nuccio

        听起来很棒:默认行为是自动清理,但用户可以选择使数据持久化。Chrome 的策略使 IndexedDB 对于离线使用毫无意义:如果我无法控制数据的持久性,我如何使用它来存储数据?

        令人难过的是,很难同时支持这两个浏览器,因为我需要在 Chrome 上使用文件系统 API,而在 Firefox 上使用 IndexedDB…

        2012 年 6 月 20 日 下午 11:23

        1. JulienW

          我认为你误解了什么。

          Chrome 支持 IndexedDB 和他们的文件系统 API,但你引用的那篇论文只讨论了文件系统 API。

          所以你也可以在 Chrome 中使用 IndexedDB。

          如果你还想支持 Safari、Opera 和移动浏览器,你可以在这里使用 shim:http://nparashuram.com/IndexedDBShim/

          2012 年 6 月 21 日 上午 12:08

          1. Todd Blanchard

            shim(以及 IndexedDB 本身)不提供任何对连接数据的支持。

            我需要 JOIN。这不是儿戏——我们有复杂的数据需求,需要对我们的数据进行复杂视图。键值存储无法满足这些需求。

            2012 年 11 月 9 日 上午 10:56

  43. Marcello Nuccio

    我知道 Chrome 支持 IndexedDB。我正在使用它,它工作得很好。唯一的问题是数据的持久性。我引用的那篇论文讨论了 HTML5 离线存储的总体情况。摘要表[1]说:IndexedDB 具有临时存储;文件系统 API 具有持久性存储。

    如果我理解正确,Firefox 不会拥有文件系统 API,但 IndexedDB 存储是(并将被选择性地设置为)持久性的。那么问题是:如何在 Chrome 和 Firefox 上确保持久性?

    [1]: https://developers.google.com/chrome/whitepapers/storage#table

    PS:在发布我的回复时,我发现了描述为 http://en.forums.wordpress.com/topic/you-are-posting-comments-too-quickly-slow-down-but-i-am-not 的问题。

    2012 年 6 月 21 日 上午 1:05

  44. Micah

    这篇文章在过去 6 个月中有什么变化吗?我看到了像这样 http://www.netmagazine.com/tutorials/make-disaster-proof-html5-forms 的文章,它让我对在未来的表单项目中使用它很感兴趣。

    2012 年 9 月 14 日 上午 12:12

    1. Robert Nyman

      我认为利弊仍然存在。

      2012 年 9 月 14 日 上午 2:01

  45. Vance Ingalls

    据我所知(我不太确定这一点),一旦页面上出现对 localStorage 的引用(编译时?),它就会阻塞线程,并从磁盘读取数据以填充 localStorage 内存以供引用。或者,如果该域过去存储过数据,它可能会在磁盘上查找数据,因此它知道 localStorage 已经在那里使用过了。

    无论哪种情况,假设我们在页面中插入了一个 iframe,该 iframe 以不同的域为源动态加载。如果我们使用这个 iframe 通过 postMessage 来进行所有 localStorage 的读写(如本文所述 http://www.nczonline.net/blog/2010/09/07/learning-from-xauth-cross-domain-localstorage/),线程是否只会在我们加载 iframe 时被阻塞?这是否为我们提供了一种使用 localStorage 的异步方法?或者我完全错了?

    2012 年 9 月 17 日 下午 4:29

  46. Stan

    只需尝试在你的数据中实现一些简单的连接和分组,你就会明白为什么 IndexedDB 是一个糟糕的选择。WebSQL 是最好的选择。

    2012 年 10 月 10 日 上午 6:37

  47. Todd Blanchard

    所以因为 SQLite 非常好,以至于每个人都选择了它,编写标准文档就成了多余的事情——我们不会在浏览器中获得真正的数据库?放弃规范工作是在两年前做出的决定。我现在正试图为智能手机和平板电脑开发一个离线 Web 应用程序,而我的选择是什么?

    在服务器端,我们使用 SQL 数据库。我们编写了一些非常巧妙的复杂查询来围绕数据提供有趣的视图。这些查询以有趣的方式进行了很多 JOIN 操作。将后端数据库中的几个表切出来,并将它们的一部分投影到浏览器的本地 SQL 数据库中,然后我们就可以在服务器和客户端上运行相同的查询(语法略有不同——很容易处理)。

    IndexedDB 缺乏 JOIN。因此,它缺乏运行我的应用程序的足够能力。这不是一个解决方案。对于那些无法理解 SQL 的人来说,也许换个职业更适合你。如果没有,我们在 github 上有一个 IndexedDBShim——一个简单的库,它在 WebSQL 之上提供了 IndexedDB API。这很容易做到,因为 IndexedDB 的能力比 WebSQL 弱。

    今天——两年后——我们毫无进展,我无法在缺乏 JOIN 的简单键值存储上支持我的应用程序。

    2012 年 11 月 9 日 上午 10:53

    1. Pete

      你为离线智能手机应用程序的选择是 WebSQL,因为几乎所有设备都由支持 WebSQL 的 Webkit 驱动。

      2012 年 11 月 10 日 上午 1:48

      1. Todd Blanchard

        是的,但我在桌面上的选择并不那么明确。

        2012 年 11 月 10 日 上午 12:01

  48. Red

    @Todd,我完全同意你的观点。

    因为没有完美的实现就拒绝 ISO 标准?那又怎样?C++、Javascript、HTML、POSIX 的实现也不完美。

    没有 SQL,我们就得回到(二进制)树和哈希了。

    我认为此举证明 Mozilla 不成熟。它迫使我回到原生开发。

    2012 年 11 月 10 日 下午 12:54

  49. Ivan

    @Pete, Todd, Red,

    有希望让 WebSQL 复活,即使只是作为一个事实上的标准吗?

    有趣的是,听说 WebSQL 甚至 localStorage 在移动环境的 webkit 中运行良好,即使资源更少。
    sqlite 被选为最初实现之一有很多原因,其中最重要的是,它在现实世界应用中证明了其能力,并且其局限性是众所周知的,但可以解决的。

    @Chris,
    作为 HTML5 的布道者,你应该带领你的团队解决浏览器实现问题,并向社区解释你的 Mozilla 平台将如何成为支持 HTML5 的最佳平台,无论是在桌面还是移动设备上。

    2012 年 12 月 2 日 下午 21:01

  50. Marco

    “有希望让 WebSQL 复活,即使只是作为一个事实上的标准吗?”

    我非常想关注此事,或者至少听听相关的消息。争论和嘲讽只能做那么多了,而且它们只能补充我们大多数人已经认识到的东西:Web 开发人员想要,如果不是需要,WebSQL。

    现在是我们开始想办法将其重新纳入规范流程的时候了。

    2012 年 12 月 16 日 上午 04:40

    1. Red

      反对 WebSQL 的主要论点是,只有一种基于 Sqlite 的实现。

      编写基于 Rhino 和 JDBC 的服务器端实现非常容易(几年前我已经写过类似的东西,所以我确定这不是问题)。

      如果这真的是一个主要障碍,WebSQL 应该很容易复活。

      不幸的是,主要的反对者是 Oracle 和 Microsoft,这两家都是数据库生产商…… 这些公司在可移植 SQL 的普及化中有很多损失。

      2013 年 2 月 5 日 上午 04:17

      1. JulienW

        不,主要论点是它容易出错,并且容易受到 SQL 注入的攻击。

        2013 年 2 月 5 日 上午 05:40

        1. Pete

          如果它容易受到 SQL 注入的攻击,那么实现是错误的。但是规范很好地处理了 SQL 调用中的参数。

          也许你能解释一下你所说的“容易出错”究竟是什么意思,让我明白。

          底线:放弃 WebSQL 而选择 IndexDB 是 Mozilla 在过去几年中犯下的最大错误之一。

          2013 年 2 月 5 日 上午 06:22

          1. JulienW

            > 也许你能解释一下你所说的“容易出错”究竟是什么意思,让我明白。

            我主要指的是字符串连接。我知道你可以使用带自动转义参数的 API 来使用 SQL,但事实是,你也可以使用字符串连接来使用它。所以开发者会这样做。因此,web 会更加不安全。

            IndexedDB 在设计上不允许这样做。

            > 底线:放弃 WebSQL 而选择 IndexDB 是 Mozilla 在过去几年中犯下的最大错误之一。

            嗯,不。

            我同意 IndexedDB 存在局限性。我相信这需要扩展(特别是 JOIN 之类的东西),但我相信这是前进的方向。

            2013 年 2 月 5 日 上午 06:48

        2. Todd Blanchard

          > 不,主要论点是它容易出错,并且容易受到 SQL 注入的攻击。

          这有什么问题呢?

          这是一个完全由一个用户拥有的本地数据库。如果用户想破解他自己的数据库,我不认为有什么问题,如果用户想搞乱他自己的数据库,我也没有问题。

          > 我主要指的是字符串连接。我知道你可以使用带自动转义参数的 API 来使用 SQL,但事实是,你也可以使用字符串连接来使用它。

          我想你没有使用过 WebSQL。API 完全基于绑定(你不会“自动转义”——你会将数据绑定到变量占位符)。

          > 我同意 IndexedDB 存在局限性。我相信这需要扩展(特别是 JOIN 之类的东西),但我相信这是前进的方向。

          这场“讨论”已经持续了一年了。IndexedDB 没有出现在更多平台上,也没有出现对关系能力的改进。而且经常提到的“在 IndexedDB 之上模拟 SQL”的论点也没有出现,如果有的话,它也有你反对的所有同样的非问题。

          我发现你的论点和 IndexedDB 毫无说服力。

          2013 年 2 月 5 日 上午 11:15

          1. Pete

            > 我知道你可以使用带自动转义参数的 API 来使用 SQL,但事实是,你也可以使用字符串连接来使用它。所以开发者会这样做。因此,web 会更加不安全。

            抱歉,但这太蠢了。你可以对任何其他 API 做同样的事情。而且有些人会将完整的 SQL 语句提交到服务器。你想对此怎么办?阻止 HTTP GET/POST 吗?

            2013 年 2 月 5 日 上午 11:23

          2. JulienW

            > 这是一个完全由一个用户拥有的本地数据库。如果用户想破解他自己的数据库,我不认为有什么问题,如果用户想搞乱他自己的数据库,我也没有问题。

            嗯,你必须知道,一个普通的 web 应用可以使用来自各种来源的输入:URL 参数,其他用户的内容等等。所以,这不仅仅是一个用户和他的数据库。

            > 我想你没有使用过 WebSQL。API 完全基于绑定(你不会“自动转义”——你会将数据绑定到变量占位符)。

            我承认我没有用过。“绑定”是正确的词,谢谢(抱歉,英语不是我的母语)。尽管如此,一些开发人员会将字符串连接起来生成 SQL 查询。因为这是可能的。

            > IndexedDB 没有出现在更多平台上
            Internet Explorer 10 呢?Chrome 呢?甚至 Blackberry 10 浏览器似乎也支持它。真的,只有 Safari 和 Opera 在这里没有改进。

            2013 年 2 月 5 日 上午 11:28

        3. Red

          @JulienW 任何基于文本的格式都容易受到注入攻击,如果使用不当。WebSQL 使用数据绑定。它是安全的。

          根据 W3C (http://www.w3.org/TR/webdatabase/),主要问题是只有 SQLite 实现

          “规范陷入僵局:所有感兴趣的实现者都使用了相同的 SQL 后端 (Sqlite),但我们需要多个独立的实现”。

          不要只考虑浏览器。服务器端的 Javascript 越来越流行。这意味着:我们需要 SQL API。

          2013 年 2 月 5 日 下午 13:07

          1. Julien Wajsberg

            Red> 我认为在服务器上使用 SQL 没有问题。但我认为我们需要比 WebSQL 更强大的东西(比如包含特定版本的 SQLite 功能的东西)。我们需要更通用的东西,以便能够使用多个数据库。你知道吗?我们有了它 :) http://nodejsdb.org/

            > WebSQL 使用数据绑定。它是安全的。
            是的,就像你现在可以在所有服务器端环境中使用数据绑定一样。尽管如此,我们仍然有 SQL 注入。

            Pete> 嘿,这是一种很好的正确方式。鼓掌鼓掌。

            IndexedDB 已经出现了,接受它,学习它,学习它的优点,使用它。这种情况不会很快改变。

            2013 年 2 月 6 日 上午 00:56

        4. Red

          @Julien
          在服务器端使用 Javascript 的目的是拥有单个 API。我们有 WebWorkers、DOM 等等。但是 IndexedDB 永远不会被认真对待,原因有很多。另一方面,WebSQL 的实现可以由一个人完成。

          Node.js 的实现是……实现,而不是标准。没有办法在另一个服务器或浏览器上运行相同的代码。我有我自己的代码,我感觉很好。不幸的是,它的可移植性为零,为零。

          你关于 SQL 注入的论点是有缺陷的。这只是在散布恐慌,仅此而已。

          有很多不学无术的开发者会写一些愚蠢的东西,结果,我们也有很多 HTML 注入。我还没看到有人要因为这个而放弃 html 吗?

          你看到过我提到的规范吗?关于这个问题有一个简短的部分。

          2013 年 2 月 6 日 上午 06:33

  51. Pete

    > 我承认我没有用过

    感谢你说明你的资格。

    2013 年 2 月 5 日 下午 12:22

    1. Todd Blanchard

      > Internet Explorer 10 呢?Chrome 呢?甚至 Blackberry 10 浏览器似乎也支持它。真的,只有 Safari 和 Opera 在这里没有改进。

      这是整个重要的移动市场。网络连接断断续续,缓慢且昂贵的地方,拥有离线存储真的很有用,并且离线操作是例行公事。优先考虑实施的方式。

      我们已经决定,我们只会在移动设备上使用 websql 来支持离线操作,而在其他情况下则需要网络。在没有 SQL 的情况下,使我们的应用程序及其不同的视图都高效,是不切实际的。

      2013 年 2 月 6 日 上午 08:14

本文的评论已关闭。