Chrome扩展程序如何将许多文件保存到用户指定的目录中?

时间:2013-11-06 00:51:10

标签: javascript google-chrome google-chrome-extension

我正在使用Chrome扩展程序作为内部工具。它的必要行为是:

  1. 作为页面操作,在查看某些Intranet页面时启用地址栏图标。
  2. 当用户点击该图标时,在页面上标识某种媒体类型(例如.jpg)的所有文件,并
  3. 将它们全部保存到用户本地驱动器上的目录中。
  4. This question has been asked before,但答案是“use NPAPI”和NPAPI is now derelict

    那么,目前实现这一目标的方法是什么?我看过的是:

    • chrome.FileSystem API ---但这不会将文件保存在任何用户可访问的位置。相反,存储的文件在未记录的目录中为hidden behind obfuscated names。用户要求将文件以其原始名称存储在可访问的目录中。
    • The HTML5 download attribute,通过创建数据:URL并以编程方式单击它。这会为每个文件弹出一个“另存为...”对话框,当单个页面上有一百个资产时,这是不可接受的。用户要求在单个图标点击之外下载文件而无需进一步交互。
    • Chrome Download API,但仅适用于测试版和开发频道。用户需要此扩展程序与主流Chrome一起使用。
    • 使用Native Messaging API创建一个只将文件保存到磁盘的小型.exe,然后将.jpg作为blob传递给它。这看起来非常麻烦,我甚至不确定如何可靠地将大blob传递给那样的EXE。

    我可以尝试另一种方法吗?

4 个答案:

答案 0 :(得分:49)

你做了很多研究。实际上,常规网页无法在没有任何插件或扩展的情况下写入用户的文件系统。此外,正如您所观察到的,HTML5 Filesystem API仅提供对虚拟文件系统的访问。

但是,您将chrome.fileSystem API与HTML5 FileSystem API混淆。与HTML FileSystem API不同,Chrome的fileSystem(app)API可以直接写入到用户指定的用户文件系统(例如~/Documents%USERPROFILE%\Documents)。

此API仅适用于Chrome 应用,而不适用于扩展程序。这不是问题,特别是因为您正在开发内部工具,因为您可以安装应用和扩展,并使用message passing在扩展(页面操作)和应用程序(文件系统访问)之间进行通信({ {3}})。


关于example:由于您的扩展程序是内部扩展程序,因此您可以强制用户访问测试版/开发人员频道以使用此API。此API的唯一限制是文件将保存在用户定义的Downloads文件夹的(子目录)中。

编辑:chrome.downloads API现在可用于所有渠道,包括稳定分支(自Chrome 31以来)。

答案 1 :(得分:6)

我担心你已经完成了你的家庭作业,这意味着你看了所有可能的选择。

实现您想要的最佳方式是(如您所述)使用支持本机应用程序并通过Native Messaging进行通信。顺便说一句,由于带宽在内部网上很少出现问题,您可能会发现传递资源(例如图像)URL并让应用程序下载并保存它们更简单。 (是的,它比简单地开发扩展程序更麻烦,但是必须做他们必须做的事情,对吗?)

另一方面,如果您愿意牺牲一点用户的开发简单性,我建议将JS5好东西(允许您在本地创建和下载文件)与JS压缩库结合使用(例如 JSZip ),因此用户只需下载一个zip文件(并且只提示一次)。顺便说一句,如果用户愿意,他/她可以选择总是在没有提示的情况下下载文件(但你已经知道了)。

答案 2 :(得分:3)

使用Native Messaging App的想法。

本机应用程序很麻烦,写入很痛苦,因为文档很差,除非你在两端都得到完全正确的JSON格式,否则你不会在控制台中看到任何东西,因为stdin和stdout被接管了。

但是,完成后你会更开心因为你可以使用标准工具(例如,Windows资源管理器,十六进制编辑器,TeamViewer ......)来查看,移动和删除文件,否则看看发生了什么。 Chrome的沙盒文件系统可以工作,但现在似乎是一个死胡同(没有其他浏览器选择它)。没有人可能为它开发第三方工具。当然,一旦一切正常,你可能不需要工具,但在那之前,调试是一场噩梦,因为你需要编写代码(以及相当多的代码)来跟踪哪些文件在哪些目录,文件版本中,剩下的磁盘空间......

答案 3 :(得分:0)

另一种内部(或可能是非内部)使用的解决方案是连接到本地或远程的Websocket服务器。

您可以将其放在background.js或content.js中(对于wss://使用https://

var ws = new WebSocket('ws://echo.websocket.org');
// var ws = new WebSocket('ws://127.0.0.1:9000');
ws.onmessage = function(res) {
    console.log('received data:', res.data);
};
ws.onopen = function() {
    ws.send('hello');
};