Firefox 网络扩展 - 读取本地文件(最后下载的文件)

Firefox web extension - read local file (last downloaded file)

我正在创建一个 Web 扩展并从 XUL 移植。我曾经能够使用

轻松读取文件
  var dJsm = Components.utils.import("resource://gre/modules/Downloads.jsm").Downloads;
  var tJsm = Components.utils.import("resource://gre/modules/Task.jsm").Task;
  var fuJsm = Components.utils.import("resource://gre/modules/FileUtils.jsm").FileUtils;
  var nsiPromptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);

  ....

  NetUtil.asyncFetch(file, function(inputStream, status) {
           if (!Components.isSuccessCode(status)) {
            return;
           }
            var data =  NetUtil.readInputStreamToString(inputStream, inputStream.available());
            var data = window.btoa(data);
            var encoded_data_to_send_via_xmlhttp = encodeURIComponent(data);
            ...
  });

以上内容将被弃用。

我可以使用 downloads.download() 来了解上次下载的内容,但我无法读取该文件,然后获取 encoded_data_to_send_via_xmlhttp

的等价物

同样在 Firefox 57 之后,这意味着我必须尝试通过单击按钮或其他方式来伪造用户操作,或者上传文件。

  Access to file:// URLs or reading files without any explicit user input 

没有一种简单的方法可以读取上次下载的文件吗?

WebExtension API 将不再允许扩展程序读取本地文件。您可以让扩展程序获得 CORS 权限,并通过 fetch()XMLHttpRequest() 直接从 URL 读取内容作为 blob 并直接存储到 IndexedDB 或内存,然后编码并发送到服务器。这带有 many restrictions and limitations,例如您可以从哪个来源读取等等。

此外,这可能会增加许多不需要的步骤。如果目前的问题似乎是为了与服务器共享下载的文件,我建议您获取最后一个 DownloadItem 对象,提取 URL ( .url) 从该对象并将 URL 发送回服务器。

这样服务器可以直接从 URL 加载(并在需要时在服务器上对其进行编码)。网络负载将大致相同(实际上要少一些,因为不涉及 Base64 编码,这会增加 33% 的大小),并且客户端的负载要少得多。服务器会将数据读取为 binary/byte 数据流;与直接从扩展程序发送数据一样。

要获取最后下载的文件,您可以从特权脚本中执行以下操作:

browser.downloads.search({
  limit: 1,
  orderBy: ["-startTime"]
})
.then(getLastDownload);

function getLastDownload(downloads) {
  if (downloads.length) {
    var url = downloads[0].url;
    // ... send url to the server and let server fetch the data from it directly
  }
}

根据this support mozilla question

(2) Local file security

Firefox limits access from pages on web servers to pages on local disk or UNC paths. [...]).

哪个解决方案?

and/or

  • 运行 客户端的小型本地网络服务器,假设服务器 运行 具有足够的权限,您最终可以通过 http:// 访问任何本地内容(但仍然不能使用 file:/ //)