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


74

我正在开发一个Chrome扩展程序以用作内部工具。它要求的行为是:

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

之前曾有人问过这个问题,但是答案是“使用NPAPI ”,现在NPAPI被遗弃了

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

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

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


7
出于好奇,我们最终通过完全放弃内部工具中的Chrome和Web UI来解决了这个问题。
Crashworks 2015年

2
好吧,这是这样做的一种方式..:D
先验的

@Crashworks,为什么不使用PPAPI而不是NPAPI?
佩里耶

@Crashworks-您搬到哪里去了?我们正在做类似的事情,并且在chrome中有很多工具。。。
Ed Williams

1
@EdWilliams是的,我们回到了使用Qt构建本机C ++应用的过程。
Crashworks

Answers:


53

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

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

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


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

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


1
+1由于问题是提到Chrome扩展程序,所以我从未考虑过Chrome应用程序(尽管现在看起来很明显):)不错!
gkalpak

4
@RobW问题是感知。人们会听到“ beta”,他们认为是“ bug”,因此,无论何时遇到任何类型的bug,他们都会认为这是由于处于beta中而引起的。
Crashworks 2013年

1
@Crashworks该chrome.downloadsAPI现在可在Chrome稳定版(31+)上使用。
Rob W


6
Chrome即将取消对Chrome应用的支持。回到广场一号,该死。
Pacerier '17

6

恐怕您已经完成家庭作业,这意味着您已经研究了所有可能的替代方法。

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

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


3

使用本机消息传递应用程序提示。

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

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


请不要破坏您的帖子。发布问题后,便已将内容授权给了Stack Overflow社区(根据CC-by-SA许可)。如果您想将此帖子与您的帐户取消关联,请参阅取消关联请求的正确途径是什么?
FelixSFD

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

是否可以使用WS将文件从内容传递到后台页面?我正在寻找一种将文件上传到服务器的现代方法,但是我所能找到的只是2014年前后的帖子/主题,那时您可以从内容脚本环境发出跨域请求。我将不胜感激任何建议……
阿曼德
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.