2010-01-28 8 views
48

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

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

Avez-vous une idée?

Répondre

27

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

Vous pouvez jeter un oeil au plugin NPAPI. Une autre façon de faire ce dont vous avez besoin est simplement d'envoyer une requête à un site web externe via XHR POST puis une autre requête GET pour récupérer le fichier qui apparaîtra comme une boîte de dialogue de sauvegarde. Par exemple, pour l'extension My Hangouts de mon navigateur, j'ai créé un utilitaire pour télécharger une photo à partir de HTML5 Canvas directement sur le disque. Vous pouvez jeter un oeil au code ici capture_gallery_downloader.js le code qui fait cela 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 à un 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, lorsque l'utilisateur clique sur le bouton de téléchargement, il utilisera l'API file HTML5 « télécharger » pour télécharger l'URI blob dans un fichier.

+0

Ce n'est pas la première fois que nous sommes en train de me rediriger sur le NPAPI. Je vais y jeter un coup d'oeil. Merci pour votre aide. –

+5

Notez que si vous envisagez de télécharger l'extension dans la galerie de Google, l'utilisation de NPAPI retardera votre publication pour une longue révision par celle-ci et pourrait même ne pas être acceptée. –

+0

Je suis d'accord avec Max. Cela retardera la publication, car il sera revu manuellement. Il serait préférable que vous ayez un serveur externe auquel vous pouvez donner accès dans votre poste et que vous téléchargiez les données via POST et que vous les récupériez via GET avec les en-têtes appropriés. –

-2

Depuis Javascript auto-hikes à votre ordinateur avec des pages Web à partir de n'importe où, il serait dangereux de lui donner la possibilité d'écrire sur votre disque.

Ce n'est pas autorisé. Pensez-vous que l'extension Chrome nécessitera une interaction de l'utilisateur? Sinon, il pourrait tomber dans la même catégorie.

5

Il n'y a aucun moyen que je connaisse pour sauver silencieusement des fichiers sur le disque de l'utilisateur, qui est ce qu'il semble que vous espérez faire. Je pense que vous pouvez demander des fichiers à sauvegarder un à la fois (invitant l'utilisateur à chaque fois) en utilisant quelque chose comme:

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

Si vous vouliez seulement inviter une fois l'utilisateur, vous pouvez saisir toutes les images en silence, zippez-les dans un paquet, puis demandez à l'utilisateur de le 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 ils ne sont que pour l'usage du développeur, dans le bac à sable, pour autant que je sache. (par exemple, la mise en cache hors connexion de Gmail.) Voir les dernières annonces de Google telles que this one.

+12

fonctionne uniquement sur Internet Explorer –

3

Google Webstore
Github

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

+0

Raspoutine? Nice ... – chb

+0

Premier lien hits 404 – therealprashant

18

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

Je suggère à ceux qui voulaient encore implémenter la fonctionnalité 'save-file-on-disk' de jeter un oeil à ce Stackoverflow post, le commentaire ci-dessous m'aide beaucoup.

Maintenant, depuis le 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 avance ask me before every download dans le paramètre chrome, nous pouvons enregistrer le fichier sans demander confirmation à l'utilisateur!

Voici ce que j'utilise (à 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 fournit toujours pas Event quand le téléchargement est terminé. fonction de rappel de chrome.downloads.download est appelée lorsque le téléchargement begin avec succès (pas terminé)

La documentation officielle sur les chrome.downloads est here.

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

+1

Ne sait pas sur 2014 mais à ce jour, il est possible d'écouter l'événement 'onChanged' qui porte l'objet' state' qui peut indiquer l'état du téléchargement (par exemple "complet"). – JSmyth

+1

@Allan, Re "* nous pouvons enregistrer le fichier sans inviter l'utilisateur à confirmer *"; Mais la barre de téléchargement en bas ne serait-elle pas ouverte lorsque vous commencez à écrire des fichiers sur la machine de l'utilisateur? Y a-t-il un moyen de le faire en silence? (Par exemple, si vous écrivez 50 fichiers sur la machine de l'utilisateur en arrière-plan) – Pacerier

+0

@Pacerier c'est l'étagère de téléchargement des appels, quand j'ai écrit la réponse, je me souviens que je dois désactiver manuellement l'étagère dans la page des options avancées. Je fais une recherche, j'ai trouvé ceci: vous pourriez être intéressant. 'SetShelfEnabled' ' chrome.downloads.setShelfEnabled (booléen activé) ' Activer ou désactiver l'étagère grise au bas de chaque fenêtre associée au profil de navigateur actuel. L'étagère sera désactivée si au moins une extension l'a désactivée. L'activation de l'étagère alors qu'au moins une autre extension est désactivée renvoie une erreur via runtime.lastError. –