【问题标题】:Reading and writing large amounts of data to a user's local storage in Firefox在 Firefox 中读取和写入大量数据到用户的本地存储
【发布时间】:2012-05-28 03:52:11
【问题描述】:

所以我们有一个复杂的 HTML5 离线应用程序,其中包含大量旧数据(我们说的是数十兆字节),我们希望读取它的副本并将其写入用户的磁盘。

我们已经让这种类型的 HTML5 IndexedDB 工作了,但是 Chrome 处理大量数据时速度非常慢(加载大约需要 10 分钟),并且当前版本的 Firefox 有一个lovely bug,它会随机且无法挽回地破坏整个数据库,所以这是 B 计划——此外,我们真的希望有一个用户可指定的文件,然后他们可以备份、邮寄等。

显然我们不能用普通的浏览器权限做到这一点,但是沙盒之外的 Firefox 扩展可以访问文件系统,我们已经掌握了使用 this extension 的基本概念。唯一的问题是,扩展通过reading and writing DOM attributes 传递数据,这对于我们正在谈论的数据量来说似乎不太理想:

但是,如果要相信this 这确实是唯一的方法,因为 Gecko 严格隔离特权页面(如我们的扩展程序)和非特权页面(如我们的网站)。还有其他解决方案吗?

【问题讨论】:

    标签: javascript html firefox plugins file-io


    【解决方案1】:

    您的扩展代码可以从网页中读取任意数据。它只需要通过获取它正在处理的任何对象的.wrappedJSObject 属性来选择加入,以获得它的“网页”视图。

    【讨论】:

    • 您能详细说明一下吗?我发现developer.mozilla.org/en/wrappedJSObject 有点难以解析,但听起来我需要构建自己的 XPCOM 组件才能使用其中的任何一个。
    • 通常当 Firefox 扩展与 DOM 对象一起工作时,它会获得一个特殊的净化视图,该视图仅显示内置 DOM 属性并隐藏所有“扩展”。如果您想查看这些扩展,您只需在对象的.wrappedJSObject 上查找它们,这会显示对象的“网页”视图。您不需要构建自己的 XPCOM 组件或任何东西。只需myObject.wrappedJSObject.expando
    • 所以,我们终于想出了如何让它发挥作用!详细信息很快将在单独的答案中提供,但赏金是你的——尽管前一个已过期,但必须等待 24 小时。
    【解决方案2】:

    首先,如果您查看了 indexedDB 选项,但没有说明为什么 mozIStorageService(又名 sqlite)不起作用。那里的异步功能与自定义 dom 事件相结合似乎很合适,但这取决于您的数据需求。

    我认为该问题的答案在于您关于如何从扩展程序获取网页数据的陈述。如果 dom 事件无法满足您的需求,那么您可能需要考虑编写 custom xpcom Component 代码,但这是一项繁重的工作。

    如果您无法做到这一点的原因与将大数据移入和移出服务器有关,那么您可以考虑使用流式读取器/转换器(包括添加 gzip 压缩转换器)......但这只是如果您的“大量旧数据”作为流有意义。

    【讨论】:

    • 根据您的链接,“存储 ... 对受信任的调用者可用,这意味着扩展程序和 Firefox 组件”和“API 目前是“解冻的”,这意味着它可能随时更改时间;事实上,自从 Firefox 推出以来,它在每个版本中都发生了一些变化,并且可能会继续这样做一段时间。”,所以这听起来 a) 严重不稳定,b) 毫无意义,因为我们需要无论如何构建和部署扩展。
    【解决方案3】:

    这是我们在经历了太多痛苦之后如何让这个工作的。向鲍里斯致敬,他为我们指明了正确的方向!

    下面的所有代码都是针对必须由用户安装才能启用此功能的 Firefox 扩展程序,并且代码位于 Coffeescript 中,因为这是我们滚动的方式。

    第一步是挂钩扩展程序的onDocumentLoad 事件,该事件在用户看到 Firefox 窗口之前触发:

      onDocumentLoad: =>
        gBrowser.addEventListener('DOMContentLoaded', @onLoad, true)
    

    因此,此后,每当用户打开窗口或选项卡时,DOMContentLoaded 就会被触发:

      onLoad: (event) =>
        doc = event.originalTarget
        loadedWindow = doc.defaultView.wrappedJSObject
    

    然后砰,用户的全新窗口出现了,可读可写!

        loadedWindow.myExtension = new myExtension()
    

    然后我们只需将我们的扩展代码挂钩到用户的窗口中,现在该窗口中的任何 JavaScript 代码(将在 DOMContentLoaded 之后初始化并运行)都可以访问我们的扩展,如下所示:

        if window.myExtension
          window.myExtension.write(data)
          data = window.myExtension.read()
        else
          alert("Install my extension, you fool")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-26
      • 1970-01-01
      • 1970-01-01
      • 2013-10-19
      • 2018-08-04
      • 1970-01-01
      • 1970-01-01
      • 2015-04-23
      相关资源
      最近更新 更多