Как сделать расширение Chrome скачать файл - PullRequest
41 голосов
/ 30 января 2011

Я создаю расширение, которое загружает mp3-файл с веб-сайта.Я пытаюсь сделать это, создав новую вкладку со ссылкой на mp3-файл, но Chrome продолжает открывать его внутри проигрывателя, а не загружать.Можно ли как-нибудь создать всплывающее окно, чтобы попросить пользователя «сохранить как» файл?

Ответы [ 5 ]

94 голосов
/ 11 июня 2014

Перемотка на 3 года, и теперь Google Chrome предлагает chrome.downloads API (начиная с Chrome 31).

После объявления разрешения "downloads" в манифесте можно инициироватьскачать с этим вызовом:

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

Если вы хотите создать содержимое файла в сценарии, вы можете использовать Blob и URL 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
  //...
});

Дополнительные параметры (например, диалог «Сохранить как», перезапись существующих файлов и т. д.) см. в документации .

.
13 голосов
/ 14 июля 2012

Я использовал вариант решения здесь

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 «передача сообщений» . По сути, вы передаете сообщение от вашего расширения (которое почти похоже на отдельную страницу) на страницу контента, с которой работает расширение. Затем у вас есть прослушиватель, который ваше расширение внедрило в контентную страницу, которая реагирует на сообщение и выполняет загрузку. Примерно так:

chrome.extension.onMessage.addListener(
  function (request, sender, sendResponse) {  
      if (request.greeting == "hello") {
          try{
              downloadCSS();
          }
          catch (err) {
              alert("Error: "+err.message);
          }
      }
  });
9 голосов
/ 11 октября 2013

Это слегка измененная версия ответа @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
}
6 голосов
/ 06 августа 2017

Вот краткий способ загрузки файла с использованием «загрузки» разрешения в манифесте Chrome с использованием решения @Xan и @ AmanicA

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"
});
5 голосов
/ 18 мая 2011

Я сделал это следующим образом в Appmator коде на Github .

Основной подход заключается в создании вашего BLOB-объекта, как вам угодно (Chrome имеет responseBlobXmlHttpRequest, чтобы вы могли это использовать), создайте iframe (скрытый, display:none), а затем назначьте src iframe как 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);

Пример использования responseBlob XmlHttpRequest (см .: 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...