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

IT技术 javascript google-chrome google-chrome-extension
2021-02-02 12:29:58

我正在开发用作内部工具的 Chrome 扩展程序。其所需的行为是:

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

以前有人问过这个问题,但当时的答案是“使用 NPAPI ”,现在 NPAPI 已废弃

那么,目前可用的方法是什么?我看过的有:

  • chrome.FileSystem API ---但这不保存任何用户访问的位置的文件。相反,存储的文件隐藏在未记录目录中的混淆名称后面用户要求文件以其原始名称存储在可访问的目录中。
  • HTML5 下载属性,通过创建 data: URL 并以编程方式单击它。这会为每个文件弹出一个“另存为...”对话框,当单个页面上有一百个资产时,这是不可接受的。用户要求下载文件时,除了单击单个图标外,无需进一步交互。
  • 浏览器下载API,但那只是在测试和开发渠道提供。用户需要此扩展程序与主流 Chrome 一起使用。
  • 通过创建一个小的 .exe 来使用Native Messaging API,该 .exe 只是将文件保存到磁盘,然后将 .jpg 作为 blob 传递给它。这看起来很麻烦,我什至不确定如何可靠地将大 blob 传递给这样的 EXE。

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

4个回答

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

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

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


关于chrome.downloads:由于您的扩展是内部的,您可能可以强制用户进入 beta/dev 频道以使用此 API。此 API 的唯一限制是文件将保存在用户定义的下载文件夹(的子目录)中。

编辑:该chrome.downloadsAPI 现在可用于所有渠道,包括稳定分支(自 Chrome 31 起)。

@Crashworks chrome.downloadsAPI 现在可在 Chrome 稳定版 (31+) 上使用。
2021-03-15 12:29:58
@RobW 问题在于感知。人们听到“测试版”,他们会想到“错误”,因此无论何时他们遇到任何类型的错误,他们都会假设这是由于处于测试阶段并来找我。
2021-03-20 12:29:58
Chrome 即将取消对 Chrome 应用程序的支持回到第一个,该死的。
2021-03-24 12:29:58
+1 由于问题提到了 Chrome 扩展程序,我从未想过 Chrome 应用程序(尽管现在看起来很明显):) 很好!
2021-04-13 12:29:58

恐怕您已经完成了功课,这意味着您已经考虑了所有可能的选择。

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

另一方面,如果您愿意为了开发的简单性而牺牲一点用户体验,我建议将 HTML5 好东西(允许您在本地创建和下载文件)与 JS 压缩库(例如JSZip)结合起来,所以用户只需要下载一个 zip 文件(并且只提示一次)。顺便说一句,如果用户愿意,他/她可以选择始终下载文件而不提示(但您已经知道了)。

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

本机应用程序很麻烦而且编写起来很痛苦,因为文档很差,除非您在两端都获得完全正确的 JSON 格式,否则您将不会在控制台中看到任何内容,因为 stdin 和 stdout 已被接管。

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

请不要破坏您的帖子。一旦你发布了一个问题,你就已经将内容授权给整个 Stack Overflow 社区(在 CC-by-SA 许可下)。如果您想将此帖子与您的帐户解除关联,请参阅解除关联请求的正确途径是什么?.
2021-03-16 12:29:58

内部(或非内部)使用的另一种解决方案是连接到本地或远程的 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');
};
是否可以使用 WS 将文件从内容传递到后台页面?我正在寻找一些将文件上传到服务器的现代方法,但我能找到的只是 2014 年左右的帖子/线程,那时您可以从内容脚本环境发出跨域请求。我很感激任何建议...
2021-04-07 12:29:58