web-dev-qa-db-fra.com

Chrome: Comment enregistrer un fichier sur le disque

Je suis en train de créer une extension pour google chrome qui peut enregistrer toutes les images ou les liens vers des images sur le disque dur.

Le problème est que je ne sais pas comment enregistrer le fichier sur le disque avec JS ou avec Google Chrome API d'extension.

Vous avez une idée?

60
X-Blaster

Vous pouvez utiliser fonctionnalités HTML5 FileSystem pour écrire sur le disque à l'aide de l'API Download . C'est le seul moyen de télécharger des fichiers sur le disque et c'est limité.

Vous pouvez jeter un œil au plugin NPAPI. Une autre façon de faire ce dont vous avez besoin est simplement d'envoyer une demande à un site Web externe via XHR POST puis une autre demande GET pour récupérer le fichier qui apparaîtra comme une boîte de dialogue d'enregistrement de fichier.

Par exemple, pour mon extension de navigateur Mes Hangouts J'ai créé un utilitaire pour télécharger une photo de HTML5 Canvas directement sur le disque. Vous pouvez jeter un œil au code ici capture_gallery_downloader.js le code qui le fait est:

var url = window.webkitURL || window.URL || window.mozURL || window.msURL;
var a = document.createElement('a');
a.download = 'MyHangouts-MomentCapture.jpg';
a.href = url.createObjectURL(dataURIToBlob(data.active, 'jpg'));
a.textContent = 'Click here to download!';
a.dataset.downloadurl = ['jpg', a.download, a.href].join(':');

Si vous souhaitez la mise en œuvre de la conversion d'un URI en Blob en HTML5, voici comment je l'ai fait:

/**
 * Converts the Data Image URI to a Blob.
 *
 * @param {string} dataURI base64 data image URI.
 * @param {string} mimetype the image mimetype.
 */
var dataURIToBlob = function(dataURI, mimetype) {
  var BASE64_MARKER = ';base64,';
  var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
  var base64 = dataURI.substring(base64Index);
  var raw = window.atob(base64);
  var rawLength = raw.length;
  var uInt8Array = new Uint8Array(rawLength);

  for (var i = 0; i < rawLength; ++i) {
    uInt8Array[i] = raw.charCodeAt(i);
  }

  var bb = new this.BlobBuilder();
  bb.append(uInt8Array.buffer);
  return bb.getBlob(mimetype);
};

Ensuite, après que l'utilisateur ait cliqué sur le bouton de téléchargement, il utilisera l'API de fichier HTML5 "télécharger" pour télécharger l'URI de blob dans un fichier.

32
Mohamed Mansour

Je souhaitais depuis longtemps créer moi-même une extension chrome pour télécharger des images par lots. Pourtant, à chaque fois, je suis frustré parce que la seule option apparemment applicable est NPAPI, que chrome et firefox semblent ne pas vouloir soutenir plus longtemps.

Je suggère à ceux qui voulaient toujours implémenter la fonctionnalité "enregistrer le fichier sur le disque" de jeter un coup d'œil à ce Stackoverflow post , le commentaire ci-dessous ce message m'aide beaucoup.

Depuis chrome 31+, l'API chrome.downloads est devenue stable. Nous pouvons l'utiliser pour télécharger un fichier par programme. Si l'utilisateur n'a pas défini l'option avancée ask me before every download dans le paramètre chrome, nous pouvons enregistrer le fichier sans inviter l'utilisateur à confirmer!

Voici ce que j'utilise (sur la page d'arrière-plan de l'extension):

    // remember to add "permissions": ["downloads"] to manifest.json
    // this snippet is inside a onMessage() listener function
    var imgurl = "https://www.google.com.hk/images/srpr/logo11w.png";
    chrome.downloads.download({url:imgurl},function(downloadId){
        console.log("download begin, the downId is:" + downloadId);
    });

Bien qu'il soit dommage que chrome ne fournisse toujours pas de Event lorsque le téléchargement est terminé .chrome.downloads.download la fonction de rappel est appelée lorsque le téléchargement begin réussit (pas le terminé)

La documentation officielle sur chrome.downloadsis ici .

Ce n'est pas mon idée originale de la solution, mais j'ai posté ici en espérant qu'elle pourrait être utile à quelqu'un.

22
Allan Ruin

Je ne connais aucun moyen d'enregistrer silencieusement des fichiers sur le lecteur de l'utilisateur, ce que vous espérez faire. Je pense que vous pouvez DEMANDER que les fichiers soient enregistrés un à la fois (en invitant l'utilisateur à chaque fois) en utilisant quelque chose comme:

function saveAsMe (filename)
{
document.execCommand('SaveAs',null,filename)
}

Si vous ne souhaitez inviter l'utilisateur qu'une seule fois, vous pouvez saisir toutes les images en silence, les compresser dans un ensemble, puis demander à l'utilisateur de les télécharger. Cela peut signifier faire XmlHttpRequest sur tous les fichiers, les compresser en Javascript, les TÉLÉCHARGER dans une zone de transit, puis demander à l'utilisateur s'il souhaite télécharger le fichier Zip. Cela semble absurde, je sais.

Il y a des options de stockage local dans le navigateur, mais elles ne sont à l'usage du développeur, dans le bac à sable, que je sache. (par exemple, la mise en cache hors ligne de Gmail.) Voir les annonces récentes de Google comme celle-ci .

5
sandover

Pensez à utiliser les fonctionnalités HTML5 FileSystem qui permettent d'écrire dans des fichiers en utilisant Javascript.

4
Arnaud Leymet

Google Webstore
Github

J'ai fait une extension qui fait quelque chose comme ça, si quelqu'un ici est toujours intéressé. Il utilise une XMLHTTPRequest pour saisir l'objet, qui dans ce cas est présumé être une image, puis lui fait une ObjectURL, un lien vers cette ObjectUrl, et clique sur le lien imaginaire.

4
DrJKL