javascript Chrome 扩展程序如何将多个文件保存到用户指定的目录?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19802032/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can a Chrome extension save many files to a user-specified directory?
提问by Crashworks
I'm working on a Chrome extension to be used as an internal tool. Its required behavior is:
我正在开发用作内部工具的 Chrome 扩展程序。其所需的行为是:
- As a page action, enable an address bar icon when looking at certain intranet pages.
- when the user clicks the icon, identify all files of a certain media type (say, .jpg) on the page, and
- silently save them all to a directory on the user's local drive.
- 作为页面操作,在查看某些 Intranet 页面时启用地址栏图标。
- 当用户单击该图标时,识别页面上特定媒体类型(例如 .jpg)的所有文件,以及
- 默默地将它们全部保存到用户本地驱动器上的目录中。
This question has been asked before, but the answer then was "use NPAPI", and NPAPI is now derelict.
以前有人问过这个问题,但当时的答案是“使用 NPAPI”,现在 NPAPI 已废弃。
So, what is the currently available way to achieve this? The ones I've looked at are:
那么,目前可用的方法是什么?我看过的有:
- The chrome.FileSystemAPI --- but this does not save files in any user-accessible location. Instead the stored files are hidden behind obfuscated namesin an undocumented directory. User requires that the files be stored under their original names in an accessible directory.
- The HTML5 download attribute, by creating a data: URL and programmatically clicking it. This pops up a "save as..." dialog for each file, which is unacceptable when there are a hundred assets on a single page. User requires that the files be downloaded without further interaction beyond the single icon click.
- The Chrome Download API, but that is only available in the beta and dev channels. User requires this extension work with mainstream Chrome.
- Use the Native Messaging APIby creating a small .exe that simply saves a file to disk, and then pass the .jpg as a blob to it. This seems very cumbersome and I am not even sure how to reliably pass large blobs to EXEs like that.
- 该chrome.FileSystemAPI ---但这不保存任何用户访问的位置的文件。相反,存储的文件隐藏在未记录目录中的混淆名称后面。用户要求文件以其原始名称存储在可访问的目录中。
- HTML5 下载属性,通过创建 data: URL 并以编程方式单击它。这会为每个文件弹出一个“另存为...”对话框,当单个页面上有一百个资产时,这是不可接受的。用户要求下载文件时,除了单击单个图标外,无需进一步交互。
- 该浏览器下载API,但那只是在测试和开发渠道提供。用户需要此扩展程序与主流 Chrome 一起使用。
- 通过创建一个小的 .exe 来使用Native Messaging API,该 .exe 只是将文件保存到磁盘,然后将 .jpg 作为 blob 传递给它。这看起来很麻烦,我什至不确定如何可靠地将大 blob 传递给这样的 EXE。
Is there another approach I can try?
我可以尝试另一种方法吗?
采纳答案by Rob W
You've done quite a lot of research. Indeed, regular web pages cannot write to the user's filesystem without any plugins or extensions. Also, the HTML5 Filesystem APIonly provides access to a virtual filesystem, as you've observed.
你已经做了很多研究。事实上,如果没有任何插件或扩展,常规网页无法写入用户的文件系统。此外,正如您所观察到的,HTML5 文件系统 API仅提供对虚拟文件系统的访问。
However, you are confusing the chrome.fileSystem
API with the HTML5 FileSystem API. Unlike the HTML FileSystem API, Chrome's fileSystem
(app) API can directly writeto the user's filesystem (e.g. ~/Documents
or %USERPROFILE%\Documents
), specified by the user.
但是,您将chrome.fileSystem
API 与 HTML5 FileSystem API混淆了。与 HTML文件系统API 不同,Chrome 的fileSystem
(应用程序)API 可以直接写入用户指定的文件系统(例如~/Documents
或%USERPROFILE%\Documents
)。
This API is only available to Chrome apps, not extensions. This is not a problem, especially since you're developing an internal tool, because you can install the app and extension, and use message passingto communicate between the extension (page action) and app (file system access) (example).
此 API 仅适用于 Chrome应用程序,不适用于扩展程序。这不是问题,特别是因为您正在开发内部工具,因为您可以安装应用程序和扩展程序,并使用消息传递在扩展程序(页面操作)和应用程序(文件系统访问)(示例)之间进行通信。
About chrome.downloads
: Since your extension is internal, you can probably force users to get on the beta/dev channel in order to use this API. The only limitation of this API is that the files will be saved in (a subdirectory of) the user-defined Downloads folder.
关于chrome.downloads
:由于您的扩展是内部的,您可能可以强制用户进入 beta/dev 频道以使用此 API。此 API 的唯一限制是文件将保存在用户定义的下载文件夹(的子目录)中。
EDIT: The chrome.downloads
API is now avaiable in all channels, including the stable branch (since Chrome 31).
编辑:该chrome.downloads
API 现在可用于所有渠道,包括稳定分支(自 Chrome 31 起)。
回答by gkalpak
I am afraid that you have done your homework, meaning you looked at all possible alternatives.
恐怕您已经完成了功课,这意味着您已经考虑了所有可能的选择。
The best way to achieve exactly what you want, would be (as you mentioned) using a supporting native app and communicating through Native Messaging. BTW, since bandwidth is rarely a problem on intranets, you might find it simpler to pass the resources (e.g. images) URLs and have the app download and save them.
(Yes, it will be more cumbersome than simply developing an extension, but one's got to do what they've got to do, right ?)
实现您想要的效果的最佳方法是(如您所提到的)使用支持本机应用程序并通过本机消息传递进行通信。顺便说一句,由于带宽在 Intranet 上很少成为问题,您可能会发现传递资源(例如图像)URL 并让应用程序下载并保存它们更简单。
(是的,这会比简单地开发一个扩展更麻烦,但一个人必须做他们必须做的事情,对吧?)
On the other hand, if you are willing to sacrifice a little bit of user's experience over simplicity of development, I suggest combining the HTML5 goodies (that allow you to create and download a file locally) with a JS zipping library (e.g. JSZip), so the user only has to download a single zip file (and is only prompted once). BTW, if the user wishes, he/she can choose to always download the files without prompting (but you knew that already).
另一方面,如果您愿意为了开发的简单性而牺牲一点用户体验,我建议将 HTML5 好东西(允许您在本地创建和下载文件)与 JS 压缩库(例如JSZip)结合起来,所以用户只需要下载一个 zip 文件(并且只提示一次)。顺便说一句,如果用户愿意,他/她可以选择始终下载文件而不提示(但您已经知道了)。
回答by DaveWalley
Use the Native Messaging App idea.
使用本机消息应用程序的想法。
The native app is cumbersome and a pain to write because documentation is poor, and unless you get the JSON formatting exactly correct on both ends you will not see anything in a console because stdin and stdout are taken over.
本机应用程序很麻烦而且编写起来很痛苦,因为文档很差,除非您在两端都获得完全正确的 JSON 格式,否则您将不会在控制台中看到任何内容,因为 stdin 和 stdout 已被接管。
But, you will be happier when it is done because you can use standard tools (e.g., Windows Explorer, a hex editor, TeamViewer...) to view, move, and delete files, and otherwise see what is going on. Chrome's sand-boxed file system works, but seems to now be a dead-end (no other browsers have picked it up). No one is likely to develop third-party tools for it. Of course you probably don't need tools once everything is working, but until then, debugging is a nightmare because you need to write code (and quite a lot of code) just to track what files are in what directories, file versions, remaining disk space...
但是,完成后您会更开心,因为您可以使用标准工具(例如,Windows 资源管理器、十六进制编辑器、TeamViewer...)来查看、移动和删除文件,以及查看正在发生的事情。Chrome 的沙盒文件系统可以工作,但现在似乎是一个死胡同(其他浏览器都没有采用)。没有人可能会为其开发第三方工具。当然,一旦一切正常,您可能不需要工具,但在那之前,调试是一场噩梦,因为您需要编写代码(以及相当多的代码)来跟踪哪些文件位于哪些目录、文件版本、剩余文件中磁盘空间...
回答by iman
Another solution for internal (or may be non-internal) usage is to connect to a websocket server, local or remote.
内部(或非内部)使用的另一种解决方案是连接到本地或远程的 websocket 服务器。
You can put it in both background.js or content.js (use wss://
for https://
)
您可以将它放在 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');
};