【问题标题】:How can a Chrome extension save many files to a user-specified directory?Chrome 扩展程序如何将许多文件保存到用户指定的目录?
【发布时间】:2013-11-17 02:19:31
【问题描述】:

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

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

This question has been asked before,但当时的答案是“use NPAPI”和NPAPI is now derelict

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

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

我可以尝试其他方法吗?

【问题讨论】:

  • 出于好奇,我们最终通过完全放弃内部工具中的 Chrome 和 Web UI 解决了这个问题。
  • 嗯,这是一种方法......:D
  • @Crashworks,为什么不使用 PPAPI 而不是 NPAPI?
  • @Crashworks - 你搬到了什么地方?我们正在做类似的事情,并且在 chrome 中有很多工具......而不是直接应用程序?
  • @EdWilliams 是的,我们又回到了使用 Qt 构建原生 C++ 应用程序。

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


【解决方案1】:

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

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

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


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

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

【讨论】:

  • +1 既然问题提到了 Chrome 扩展,我从没想过 Chrome 应用程序(尽管现在看起来很明显):) 很好!
  • @RobW 问题在于感知。人们听到“测试版”,他们认为“错误”,因此无论何时遇到任何类型的错误,他们都会认为这是由于处于测试阶段并来找我。
  • @Crashworks chrome.downloads API 现在可在 Chrome 稳定版 (31+) 上使用。
  • Chrome 即将取消对 Chrome 应用的支持。回到第一格,该死的。
【解决方案2】:

恐怕您已经完成了作业,这意味着您已经查看了所有可能的替代方案。

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

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

【讨论】:

    【解决方案3】:

    使用原生消息应用程序的想法。

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

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

    【讨论】:

    【解决方案4】:

    内部(或可能是非内部)使用的另一种解决方案是连接到本地或远程 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 年左右的帖子/线程,那时您可以从内容脚本环境发出跨域请求。我会很感激任何建议...
    猜你喜欢
    • 2020-11-03
    • 2016-03-27
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 2015-05-20
    • 2023-04-07
    • 1970-01-01
    相关资源
    最近更新 更多