Javascript 使 Chrome 扩展程序下载文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4845215/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:22:12  来源:igfitidea点击:

Making a Chrome Extension download a file

javascripthtmlgoogle-chromegoogle-chrome-extension

提问by Franz Payer

I am creating an extension that will download a mp3 file off a website. I am trying to do this by creating a new tab with the link to the mp3 file, but chrome keeps opening it inside the player instead of downloading it. Is there any way I can create a pop-up to ask the user to "save-as" the file?

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

回答by Xan

Fast-forward 3 years, and now Google Chrome offers chrome.downloadsAPI(since Chrome 31).

快进 3 年,现在 Google Chrome 提供chrome.downloadsAPI(自 Chrome 31 起)。

After declaring "downloads"permission in the manifest, one can initiate a download with this call:

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

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

If you want to generate the file content in the script, you can use Bloband URLAPIs, e.g.:

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

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
  //...
});

For more options (i.e. Save As dialog, overwriting existing files, etc.), see the documentation.

有关更多选项(即另存为对话框、覆盖现有文件等),请参阅文档

回答by Steve Mc

I used a variation on the solution 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
}

One thing you need to bare in mind is that this code needs to execute on the page and not your extension - otherwise the user won't see the download action that chrome does. The download will still happen and you will be able to see it in the download tab, but they won't see the actual download happen.

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

Edit(afterthought about making your code execute on the content page):

编辑(事后考虑让您的代码在内容页面上执行):

The way you make an action occur on the content page rather than your extension is to use Chrome "message passing". Basically, you pass a message from your extension (which is almost like a separate page) to the content page that the extension is working with. You then have a listener that your extension has injected into the content page that reacts to the message and does the download. Something like this:

您在内容页面而不是扩展程序上执行操作的方式是使用 Chrome “消息传递”。基本上,您将来自扩展程序的消息(几乎就像一个单独的页面)传递到扩展程序正在使用的内容页面。然后,您有一个侦听器,您的扩展程序已将其注入内容页面,该页面对消息做出反应并进行下载。像这样的东西:

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

回答by AmanicA

This is a slightly modified version of @Steve Mc's answer that just makes it into a generalized function that can easily be copied and used as is:

这是@Steve Mc's answer的一个稍微修改的版本,它只是使它成为一个可以轻松复制和按原样使用的通用函数:

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
}

回答by Apoorv Saxena

Here's a concise way to download a file using "downloads"permission in Chrome manifest using @Xan and @AmanicA's solution

这是使用@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"
});

回答by Kinlan

I did it as follows in Appmatorcode on Github.

我在Github上的Appmator代码中做了如下操作

The basic approach is to build your Blob, however you want (Chrome has a responseBlob on XmlHttpRequest so you can use that), create an iframe (hidden, display:none) then assign the src of the iframe to be the Blob.

基本方法是根据需要构建 Blob(Chrome 在 XmlHttpRequest 上有一个 responseBlob,因此您可以使用它),创建一个 iframe(隐藏,display:none),然后将 iframe 的 src 分配为 Blob。

This will initiate a download and save it to the filesystem. The only problem is, you can't set the filename yet.

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

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);

An example of using XmlHttpRequest's responseBlob (see: http://www.w3.org/TR/XMLHttpRequest2/#dom-xmlhttprequest-responseblob)

使用 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);
}