使Chrome扩展程序下载文件

时间:2011-01-30 20:13:07

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

我正在创建一个从网站上下载mp3文件的扩展程序。我试图通过创建一个带有mp3文件链接的新选项卡来做到这一点,但chrome继续在播放器中打开它而不是下载它。有什么方法可以创建一个弹出窗口来要求用户“另存为”文件吗​​?

5 个答案:

答案 0 :(得分:93)

快进3年,现在谷歌浏览器提供chrome.downloads API(自Chrome 31以来)。

在清单中声明"downloads"权限后,可以通过此调用启动下载:

chrome.downloads.download({
  url: "http://your.url/to/download",
  filename: "suggested/filename/with/relative.path" // Optional
});

如果要在脚本中生成文件内容,可以使用BlobURL API,例如:

var blob = new Blob(["array of", " parts of ", "text file"], {type: "text/plain"});
var url = URL.createObjectURL(blob);
chrome.downloads.download({
  url: url // The object URL can be used as download URL
  //...
});

有关更多选项(例如“另存为”对话框,覆盖现有文件等),请参阅documentation

答案 1 :(得分:13)

我在解决方案here

上使用了变体
var downloadCSS = function () {
    window.URL = window.webkitURL || window.URL;
    file = new BlobBuilder(); //we used to need to check for 'WebKitBlobBuilder' here - but no need anymore
    file.append(someTextVar); //populate the file with whatever text it is that you want
    var a = document.createElement('a');
    a.href = window.URL.createObjectURL(file.getBlob('text/plain'));
    a.download = 'combined.css'; // set the file name
    a.style.display = 'none';
    document.body.appendChild(a);
    a.click(); //this is probably the key - simulatating a click on a download link
    delete a;// we don't need this anymore
}

您需要记住的一件事是,此代码需要在页面上执行而不是在您的扩展程序上执行 - 否则用户将看不到Chrome执行的下载操作。下载仍然会发生,您可以在下载选项卡中看到它,但他们不会看到实际的下载。

编辑(关于在内容页面上执行代码的事后想法):

您在内容网页上执行操作的方式,而不是您的扩展程序是使用Chrome "message passing"。基本上,您将邮件从您的扩展程序(几乎就像一个单独的页面)传递到扩展程序正在使用的内容页面。然后,您有一个监听器,您的扩展已注入内容页面,该内容页面对消息作出反应并进行下载。像这样:

chrome.extension.onMessage.addListener(
  function (request, sender, sendResponse) {  
      if (request.greeting == "hello") {
          try{
              downloadCSS();
          }
          catch (err) {
              alert("Error: "+err.message);
          }
      }
  });

答案 2 :(得分:9)

这是@Steve Mc的答案的略微修改版本,它只是使其成为一个可以轻松复制和使用的通用函数:

function exportInputs() {
    downloadFileFromText('inputs.ini','dummy content!!')
}

function downloadFileFromText(filename, content) {
    var a = document.createElement('a');
    var blob = new Blob([ content ], {type : "text/plain;charset=UTF-8"});
    a.href = window.URL.createObjectURL(blob);
    a.download = filename;
    a.style.display = 'none';
    document.body.appendChild(a);
    a.click(); //this is probably the key - simulating a click on a download link
    delete a;// we don't need this anymore
}

答案 3 :(得分:6)

这是使用@Xan和@AmanicA解决方案在Chrome清单中使用"下载" 权限下载文件的简明方法

function downloadFile(options) {
    if(!options.url) {
        var blob = new Blob([ options.content ], {type : "text/plain;charset=UTF-8"});
        options.url = window.URL.createObjectURL(blob);
    }
    chrome.downloads.download({
        url: options.url,
        filename: options.filename
    })
}

// Download file with custom content
downloadFile({
  filename: "foo.txt",
  content: "bar"
});

// Download file from external host
downloadFile({
  filename: "foo.txt",
  url: "http://your.url/to/download"
});

答案 4 :(得分:5)

我在Appmator上的Github代码中执行了以下操作。

基本方法是构建你的Blob,无论你想要什么(Chrome在XmlHttpRequest上有一个responseBlob,你可以使用它),创建一个iframe(隐藏,display:none)然后分配iframe的src为Blob。

这将启动下载并将其保存到文件系统。唯一的问题是,你还不能设置文件名。

var bb = new (window.BlobBuilder || window.WebKitBlobBuilder)();

var output = Builder.output({"binary":true});
var ui8a = new Uint8Array(output.length);

for(var i = 0; i< output.length; i++) {
  ui8a[i] = output.charCodeAt(i);
}

bb.append(ui8a.buffer);

var blob = bb.getBlob("application/octet-stream");
var saveas = document.createElement("iframe");
saveas.style.display = "none";

if(!!window.createObjectURL == false) {
  saveas.src = window.webkitURL.createObjectURL(blob); 
}
else {
  saveas.src = window.createObjectURL(blob); 
}

document.body.appendChild(saveas);

使用XmlHttpRequest的responseBlob的示例(请参阅:http://www.w3.org/TR/XMLHttpRequest2/#dom-xmlhttprequest-responseblob

var xhr = new XmlHttpRequest();
xhr.overrideMimeType("application/octet-stream"); // Or what ever mimeType you want.
xhr.onreadystatechanged = function() {
if(xhr.readyState == 4 && xhr.status == 200) {

  var blob = xhr.responseBlob();
  var saveas = document.createElement("iframe");
  saveas.style.display = "none";

  if(!!window.createObjectURL == false) {
    saveas.src = window.webkitURL.createObjectURL(blob); 
  }
  else {
    saveas.src = window.createObjectURL(blob); 
  }

  document.body.appendChild(saveas);
}