web-dev-qa-db-fra.com

Création d'une extension Chrome Télécharger un fichier

Je crée une extension qui téléchargera un fichier mp3 sur un site Web. J'essaie de le faire en créant un nouvel onglet avec le lien vers le fichier mp3, mais chrome continue de l'ouvrir dans le lecteur au lieu de le télécharger. Existe-t-il un moyen de créer une pop -up pour demander à l'utilisateur de "sauvegarder sous" le fichier?

43
Franz Payer

Avance rapide de 3 ans, et maintenant Google Chrome propose chrome.downloads API (depuis Chrome 31).

Après avoir déclaré "downloads" autorisation dans le manifeste, on peut lancer un téléchargement avec cet appel:

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

Si vous souhaitez générer le contenu du fichier dans le script, vous pouvez utiliser les API Blob et URL , par exemple:

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

Pour plus d'options (c'est-à-dire la boîte de dialogue Enregistrer sous, écraser les fichiers existants, etc.), consultez la documentation .

97
Xan

J'ai utilisé une variante de la solution ici

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
}

Une chose que vous devez garder à l'esprit est que ce code doit être exécuté sur la page et non sur votre extension - sinon l'utilisateur ne verra pas l'action de téléchargement que fait chrome. Le téléchargement continuera arriver et vous pourrez le voir dans l'onglet de téléchargement, mais ils ne verront pas le téléchargement réel se produire.

Modifier (après avoir pensé à faire exécuter votre code sur la page de contenu):

La façon dont vous effectuez une action sur la page de contenu plutôt que sur votre extension consiste à utiliser Chrome "passage de message" . Fondamentalement, vous passez un message de votre extension ( qui est presque comme une page séparée) à la page de contenu avec laquelle l'extension fonctionne. Vous avez alors un écouteur que votre extension a injecté dans la page de contenu qui réagit au message et effectue le téléchargement. Quelque chose comme ceci:

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

Il s'agit d'une version légèrement modifiée de la réponse de @Steve Mc qui en fait simplement une fonction généralisée qui peut facilement être copiée et utilisée telle quelle:

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
}
9
AmanicA

Voici un moyen concis de télécharger un fichier en utilisant "téléchargements" permission dans Chrome en utilisant @Xan et la solution @ 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"
});
7
Apoorv Saxena

Je l'ai fait comme suit dans Appmator code sur Github .

L'approche de base consiste à créer votre Blob, comme vous le souhaitez (Chrome a un responseBlob sur XmlHttpRequest pour que vous puissiez l'utiliser), créez un iframe (caché, display:none) puis affectez le src de l'iframe au Blob.

Cela lancera un téléchargement et l'enregistrera dans le système de fichiers. Le seul problème est que vous ne pouvez pas encore définir le nom de fichier.

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

Un exemple d'utilisation de responseBlob de XmlHttpRequest (voir: 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);
}
5
Kinlan