【问题标题】:Intercept new downloads in Firefox Addon SDK拦截 Firefox Addon SDK 中的新下载
【发布时间】:2014-06-28 10:53:52
【问题描述】:

我已经为 Windows 编写了一个简单的下载管理器,我想为 Firefox 创建一个插件,当启用该插件时,它会拦截 Firefox 中的新下载并将它们发送到下载管理器。

我已经为 Google Chrome 使用:

chrome.downloads.onCreated.addListener(function(details) {
    // stop the download
    chrome.downloads.cancel(details.id, null);
}

问题是如何使用 Firefox 插件 SDK 实现类似的功能。

我看到有一种拦截页面加载以查看内容/标题的方法,这可能会有所帮助,但我不知道请求是否会变成下载。

Firefox add-on SDK: Get http response headers

我也许可以寻找不是 text/html 的内容类型或检查内容处置标头,但如果我不能正确处理所有情况,这可能会导致问题。

是否无法使用 JS SDK 访问下载管理器,或者无法知道下载何时开始/开始并停止下载?

【问题讨论】:

    标签: javascript firefox-addon firefox-addon-sdk


    【解决方案1】:

    链接问题讨论的http-on-examine-response 观察者是错误的方法。它涉及所有请求,而不仅仅是下载。

    改为使用Downloads.jsm 观察新的下载,然后取消它们,依此类推。

    要在 SDK 中加载 Downloads.jsm,请使用:

    const {Cu} = require("chrome");
    Cu.import("resource://gre/modules/Downloads.jsm");
    Cu.import("resource://gre/modules/Task.jsm");
    

    然后你就可以添加你的监听器了。

    let view = {
      onDownloadAdded: function(download) { 
        console.log("Added", download);
      },
      onDownloadChanged: function(download) {
        console.log("Changed", download);
      },
      onDownloadRemoved: function(download) {
        console.log("Removed", download);
      }
    };
    
    Task.spawn(function() {
      try {
        let list = yield Downloads.getList(Downloads.ALL);
        yield list.addView(view);
      } catch (ex) {
        console.error(ex);
      }
    });
    

    链接的 MDN 文档有更多信息和示例。

    由于您的插件是无需重启的 SDK 插件,您需要在卸载时使用 .removeView 再次删除侦听器,否则会出现内存泄漏。

    【讨论】:

    • 这看起来正是我正在寻找的东西,但我刚刚运行了一个快速测试,将其复制到我的代码中并尝试下载文件,但我从未看到“已添加”,“日志中的“已更改”或“已删除”条目?
    • 没关系,我现在已经添加了产量 list.addView(view);行
    • @miked,代码中显然存在语法错误。这就是您从文档中重新占用示例代码所得到的:p 我修复了这个问题并稍微改进了示例并确保它确实有效;)
    • 好的,还修复了 MDN 中损坏的示例代码(我希望):p
    【解决方案2】:

    这是 JSM 方式。

    Components.utils.import("resource://gre/modules/Downloads.jsm");
    Components.utils.import("resource://gre/modules/Task.jsm");
    Components.utils.import("resource://gre/modules/FileUtils.jsm");
    
    var view = {
        onDownloadChanged: function (download) {
            console.log(download, 'Changed');
            if (download.succeeded) {
                var file = new FileUtils.File(this.target.path);
                console.log('file', file);
            }
        }
    };
    
    var list;
    Task.spawn(function () {
        list = yield Downloads.getList(Downloads.ALL);
        list.addView(view);
    }).then(null, Components.utils.reportError);
    

    记得removeView 停止收听。可以在任何地方执行此操作,例如在 shutdown 函数或其他任何地方,不必在 Task.spawn 内,所以 list 必须是全局变量。

    list.removeView(view); //to stop listening
    

    这是旧方法,似乎仍然有效。虽然我以为他们说他们要取出旧的 downloadManager:

    var observerService = Components.classes["@mozilla.org/download-manager;1"].getService(Components.interfaces.nsIDownloadManager);
    
    observerService.addListener({
        onDownloadStateChange: function (state, dl) {
            console.log('dl=', dl);
            console.log('state=', state);
            console.log('targetFile', dl.targetFile);
            if (state == 7 && dl.targetFile.leafName.substr(-4) == ".txt") {
                //guys just downloaded (succesfully) a .txt file
            }
        }
    });
    

    这是一个 mozillazine 以及更多内容:http://forums.mozillazine.org/viewtopic.php?f=19&t=2792021

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多