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

我正在开发一个 Chrome 扩展作为内部工具,它需要的行为是:

  1. 作为页面操作,在查看某些内部网页时启用地址栏图标。
  2. 当用户单击图标时,在页面上标识特定媒体类型(比如. jpg)的所有文件,并且
  3. 以静默方式将它们全部保存到用户本地驱动器上的一个目录中。

这个问题之前已经被问过了,但是当时的答案是“ 使用 NPAPI”和“ NPAPI 现在被废弃了”。

那么,目前可行的方法是什么呢? 我看到的是:

  • Chrome 文件系统 API ——-但是这不会将文件保存在任何用户可访问的位置。相反,存储的文件是 隐藏在模糊的名字后面,位于一个未记录的目录中。用户要求将这些文件以其原始名称存储在一个可访问的目录中。
  • HTML5下载属性 ,通过创建一个 data: URL 并以编程方式单击它。这会为每个文件弹出一个“另存为...”对话框,当一个页面上有100个资产时,这是不可接受的。用户要求下载的文件没有进一步的交互超过单击图标。
  • Chrome 下载 API,但是它只能在 beta 和 dev 通道中使用。用户需要这个扩展工作与主流 Chrome。
  • 使用 本机消息 API创建一个小的。将文件保存到磁盘,然后将。作为它的一个斑点。这似乎非常麻烦,我甚至不知道如何可靠地传递大的 blobs 到 EXE 这样的。

还有别的办法吗?

34970 次浏览

恐怕你已经做了功课,也就是说你已经考虑了所有可能的选择。

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

另一方面,如果你愿意牺牲一点点用户体验而不是简单的开发,我建议将 HTML5的好处(允许你在本地创建和下载一个文件)和一个 JS 压缩库(例如 Rel = “ norefrer”> JSZip < a href = “ http://stuk.github.io/JSZip/”rel = “ norefrer”> JSZip )结合起来,这样用户只需要下载一个压缩文件(并且只提示一次)。顺便说一句,如果用户愿意,他/她可以选择总是下载文件而不提示(但你已经知道了)。

你做了很多研究。事实上,没有任何插件或扩展,普通的网页无法写入用户的文件系统。而且,正如你所观察到的,HTML5文件系统 API只提供对虚拟档案系统的访问。

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

这个 API 只适用于 Chrome应用程序,而不是扩展。这不是问题,特别是因为您正在开发一个内部工具,因为您可以安装应用程序和扩展,并使用 传递信息在扩展(页面操作)和应用程序(文件系统访问)(例子)之间进行通信。


关于 chrome.downloads: 因为您的扩展是内部的,所以您可以强制用户登录 beta/dev 通道来使用这个 API。此 API 的唯一限制是文件将保存在用户定义的 Downloads 文件夹中(子目录)。

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

使用本机消息应用程序的想法。

本地应用程序很麻烦,而且编写起来很痛苦,因为文档很差,除非两端的 JSON 格式都完全正确,否则在控制台中什么都看不到,因为 stdin 和 stdout 被接管了。

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

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

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

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');
};