Utiliser HTML5 / Javascript pour générer et enregistrer un fichier

j'ai joué avec WebGL dernièrement, et J'ai obtenu un lecteur Collada travailler. Le problème est qu'il est assez lent (Collada est un format très verbeux), donc je vais commencer à convertir des fichiers à un format plus facile à utiliser (probablement JSON). Chose est, j'ai déjà le code pour parser le fichier en Javascript, donc je peut aussi bien l'utiliser comme mon exportateur trop! Le problème est de les sauver.

Maintenant, je sais que je peux analyser le fichier, envoyer le résultat sur le serveur et le navigateur demande le fichier à partir du serveur de téléchargement. Mais en réalité, le serveur n'a rien à voir avec ce processus particulier, alors pourquoi créer? J'ai déjà le contenu du fichier en mémoire. Y a-t-il un moyen de présenter à l'utilisateur un téléchargement utilisant javascript pur? (J'en doute, mais pourrait tout aussi bien demander...)

et pour être clair: je n'essaie pas d'accéder au système de fichiers à l'insu des utilisateurs! L'utilisateur fournira un fichier (probablement par l'intermédiaire de glisser - déposer), le script va transformer le fichier en mémoire, et l'utilisateur sera invité à télécharger le résultat. Toutes ces activités devraient être "sans danger" en ce qui concerne le navigateur.

[EDIT]: Je ne l'ai pas mentionné à l'avance, de sorte que les affiches qui ont répondu "Flash" sont assez valides, mais une partie de ce que je fais est une tentative de mettre en évidence ce qui peut être fait avec HTML5 pure... si le Flash est à droite dans mon cas. (Bien que ce soit une réponse parfaitement valable pour tous ceux qui font une "vraie" application web.) Cela étant le cas, il semble que je suis hors de la chance, sauf si je veux faire participer le serveur. Merci quand même!

276
demandé sur Toji 2010-05-24 18:16:34

14 réponses

OK, créer une donnée:URI fait certainement l'affaire pour moi, grâce à Matthew et Dennkster pointant cette option! Voici en gros comment je le fais:

1) Obtenez tout le contenu dans une chaîne appelée "content" (par exemple en le créant initialement ou en lisant innerHTML de la balise d'une page déjà construite).

2) Construire L'URI de données:

uriContent = "data:application/octet-stream," + encodeURIComponent(content);

il y aura des limites de longueur selon le type de navigateur, etc., mais par exemple Firefox 3.6.12 fonctionne jusqu'à au moins 256k. Encoder en Base64 à la place en utilisant encodeURIComponent pourrait rendre les choses plus efficaces, mais pour moi c'était ok.

3) ouvrez une nouvelle fenêtre et "redirigez-la" vers cette URI invite pour un lieu de téléchargement de ma page JavaScript générée:

newWindow = window.open(uriContent, 'neuesDokument');

C'est ça.

236
répondu Nøk 2015-09-28 15:00:53

la solution la plus Simple pour HTML5 prêt navigateurs...

function download(filename, text) {
    var pom = document.createElement('a');
    pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
    pom.setAttribute('download', filename);

    if (document.createEvent) {
        var event = document.createEvent('MouseEvents');
        event.initEvent('click', true, true);
        pom.dispatchEvent(event);
    }
    else {
        pom.click();
    }
}

Utilisation

download('test.txt', 'Hello world!');
247
répondu Matěj Pokorný 2015-02-16 11:44:32

HTML5 défini un window.saveAs(blob, filename) la méthode. Elle n'est prise en charge par aucun navigateur pour le moment. Mais il existe une bibliothèque de compatibilité appelée FileSaver.js qui ajoute cette fonction à la plupart des navigateurs modernes (y compris Internet Explorer 10+). Internet Explorer 10 supporte une méthode navigator.msSaveBlob(blob, filename) ( MSDN ), qui est utilisée dans FileSaver.js pour le support D'Internet Explorer.

j'ai écrit un blog poster avec plus les détails à propos de ce problème.

76
répondu panzi 2014-08-24 17:22:45

enregistrer de gros fichiers

URIs de données longues peuvent donner des problèmes de performance dans les navigateurs. Une autre option pour enregistrer les fichiers générés côté client, est de mettre leur contenu dans un objet Blob (ou fichier) et de créer un lien de téléchargement en utilisant URL.createObjectURL(blob) . Ceci renvoie une URL qui peut être utilisée pour récupérer le contenu du blob. Le blob est stocké dans le navigateur jusqu'à ce que URL.revokeObjectURL() soit appelé sur L'URL ou le document qui l'a créé est fermé. La plupart des navigateurs web ont prise en charge pour les URLs d'objet , Opera Mini est le seul qui ne les supporte pas.

forcer un téléchargement

si les données sont un texte ou une image, le navigateur peut ouvrir le fichier, au lieu de le sauvegarder sur le disque. Pour faire télécharger le fichier en cliquant sur le lien, vous pouvez utiliser l'attribut download . Cependant, tous les navigateurs web ne sont pas pris en charge par pour l'attribut download. . Une autre option est d'utiliser application/octet-stream comme type mime du fichier, mais cela fait que le fichier est présenté comme un blob binaire qui est particulièrement peu convivial si vous ne spécifiez pas ou ne pouvez pas spécifier un nom de fichier. Voir aussi " de la Force à ouvrir", "Enregistrer sous"..."popup ouverte au texte, cliquez sur le lien pour le pdf dans le HTML '.

spécifiant un nom de fichier

si le blob est créé avec le constructeur de fichiers, vous pouvez également définir un nom de fichier, mais seulement quelques les navigateurs web (y compris Chrome & Firefox) ont la prise en charge du constructeur de fichiers . Le nom de fichier peut aussi être spécifié comme argument de l'attribut download , mais il est sujet à une tonne de considérations de sécurité . Internet Explorer 10 et 11 fournit sa propre méthode, msSaveBlob , pour spécifier un nom de fichier.

exemple de code

var file;
var data = [];
data.push("This is a test\n");
data.push("Of creating a file\n");
data.push("In a browser\n");
var properties = {type: 'text/plain'}; // Specify the file's mime-type.
try {
  // Specify the filename using the File constructor, but ...
  file = new File(data, "file.txt", properties);
} catch (e) {
  // ... fall back to the Blob constructor if that isn't supported.
  file = new Blob(data, properties);
}
var url = URL.createObjectURL(file);
document.getElementById('link').href = url;
<a id="link" target="_blank" download="file.txt">Download</a>
34
répondu bcmpinc 2018-03-07 14:10:48
function download(content, filename, contentType)
{
    if(!contentType) contentType = 'application/octet-stream';
        var a = document.createElement('a');
        var blob = new Blob([content], {'type':contentType});
        a.href = window.URL.createObjectURL(blob);
        a.download = filename;
        a.click();
}
32
répondu Yassir Ennazk 2013-10-07 17:03:17

jetez un oeil à de Doug Neiner pour télécharger qui est une interface JavaScript basée sur Flash pour le faire.

Downloadify est une bibliothèque JavaScript + Flash minuscule qui permet la génération et l'économie de fichiers à la volée, dans le navigateur, sans interaction de serveur.

26
répondu Pekka 웃 2011-05-27 15:04:08

Solution Simple!

<a download="My-FileName.txt" href="data:application/octet-stream,HELLO-WORLDDDDDDDD">Click here</a>    

Fonctionne dans tous les navigateurs Modernes (Voir DÉMO ).

p. S. href peut aussi être configuré avec Javascript:

'data:application/octet-stream,' + encodeURIComponent(content);

14
répondu T.Todua 2016-11-15 19:02:11

vous pouvez générer un URI de données . Toutefois, il existe des limites propres au navigateur.

10
répondu Matthew Flaschen 2010-05-24 14:22:46
J'ai utilisé FileSaver ( ) https://github.com/eligrey/FileSaver.js ) et ça marche très bien.

Par exemple, j'ai fait cette fonction pour exporter les journaux affichés sur une page.

Vous devez passer un tableau pour l'instanciation de la tache, donc je n'ai peut-être pas écrit cela de la bonne façon, mais ça marche pour moi.

Juste au cas où, soyez prudent avec le replace: c'est la syntaxe pour rendre ce global, sinon elle ne remplacera que la première qu'il rencontrera.

exportLogs : function(){
    var array = new Array();

    var str = $('#logs').html();
    array[0] = str.replace(/<br>/g, '\n\t');

    var blob = new Blob(array, {type: "text/plain;charset=utf-8"});
    saveAs(blob, "example.log");
}
9
répondu Razakhel 2014-02-10 12:56:01

j'ai trouvé deux approches simples qui fonctionnent pour moi. Tout d'abord, en utilisant un élément déjà cliqué a et en injectant les données de téléchargement. Et deuxièmement, générer un élément a avec les données de téléchargement, exécuter a.click() et le supprimer à nouveau. Mais la seconde approche ne fonctionne que si elle est invoquée par une action de clic utilisateur. (Certains) bloc de navigateur click() d'autres contextes comme lors du chargement ou déclenché après un timeout (setTimeout).

<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="UTF-8">
    <script type="text/javascript">
      function linkDownload(a, filename, content) {
        contentType =  'data:application/octet-stream,';
        uriContent = contentType + encodeURIComponent(content);
        a.setAttribute('href', uriContent);
        a.setAttribute('download', filename);
      }
      function download(filename, content) {
        var a = document.createElement('a');
        linkDownload(a, filename, content);
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
      }
    </script>
   </head>
  <body>
    <a href="#" onclick="linkDownload(this, 'test.txt', 'Hello World!');">download</a>
    <button onclick="download('test.txt', 'Hello World!');">download</button>
  </body>
</html>
8
répondu maikel 2014-09-22 10:26:02

voici un lien vers la méthode de données URI suggérée par Mathew, cela a fonctionné sur safari, mais pas bien parce que je n'ai pas pu définir le type de fichier, il est enregistré comme "unknown" et puis je dois y retourner plus tard et le modifier afin de visualiser le fichier...

http://www.nihilogic.dk/labs/canvas2image /

6
répondu Dennkster 2010-09-14 14:41:18

vous pouvez utiliser localStorage. C'est l'équivalent Html5 des cookies. Il semble fonctionner sur Chrome et Firefox, mais sur Firefox, j'ai dû le télécharger sur un serveur. C'est-à-dire, tester directement sur mon ordinateur personnel n'a pas fonctionné.

je travaille sur des exemples HTML5. Aller à http://faculty.purchase.edu/jeanine.meyer/html5/html5explain.html et faites défiler vers le labyrinthe. Les informations pour reconstruire le labyrinthe sont stockées en utilisant localStorage.

je suis venu à cet article à la recherche de JavaScript HTML5 pour le chargement et le travail avec des fichiers xml. Est-ce la même chose que l'ancien html et JavaScript????

4
répondu Jeanine 2010-06-01 19:03:37

comme mentionné précédemment le fichier API, avec le FileWriter et FileSystem API peuvent être utilisés pour stocker des fichiers sur la machine d'un client à partir du contexte d'un onglet/fenêtre de navigateur.

cependant, il y a plusieurs choses relatives à ces deux derniers IPA dont vous devez être au courant:

  • à l'heure actuelle, la mise en œuvre des IPA n'existe qu'à partir du chrome. les navigateurs (Chrome Et Opera)
  • les deux API ont été retirées de la piste standard du W3C le 24 avril 2014, et sont désormais propriétaires""
  • la suppression des API (maintenant propriétaires) de la mise en œuvre des navigateurs à l'avenir est une possibilité
  • A sandbox (un emplacement sur le disque à l'extérieur duquel les fichiers ne peuvent pas produire d'effet) est utilisé pour stocker les fichiers créés avec L'API
  • A virtual file system (une structure de répertoire qui n'existe pas nécessairement sur le disque sous la même forme qu'elle lorsqu'elle est consultée à partir de l'intérieur du navigateur) est utilisé représentent les fichiers créés avec L'API

Voici des exemples simples de la façon dont les API sont utilisées, directement et indirectement, en tandem pour ce faire:

BakedGoods *

bakedGoods.get({
        data: ["testFile"],
        storageTypes: ["fileSystem"],
        options: {fileSystem:{storageType: Window.PERSISTENT}},
        complete: function(resultDataObj, byStorageTypeErrorObj){}
});

utilisant le fichier brut, le FileWriter, et le système de fichiers APIs

function onQuotaRequestSuccess(grantedQuota)
{

    function saveFile(directoryEntry)
    {

        function createFileWriter(fileEntry)
        {

            function write(fileWriter)
            {
                var dataBlob = new Blob(["Hello world!"], {type: "text/plain"});
                fileWriter.write(dataBlob);              
            }

            fileEntry.createWriter(write);
        }

        directoryEntry.getFile(
            "testFile", 
            {create: true, exclusive: true},
            createFileWriter
        );
    }

    requestFileSystem(Window.PERSISTENT, grantedQuota, saveFile);
}

var desiredQuota = 1024 * 1024 * 1024;
var quotaManagementObj = navigator.webkitPersistentStorage;
quotaManagementObj.requestQuota(desiredQuota, onQuotaRequestSuccess);

bien que le système de fichiers et les API de FileWriter ne soient plus sur la voie des standards, leur utilisation peut être justifiée dans certains cas, à mon avis, parce que:

  • un regain d'intérêt de la part des vendeurs de navigateur de mise en œuvre des Nations Unies peut les y remettre
  • pénétration du marché de la mise en œuvre (à base de Chrome) navigateurs est élevé
  • Google (le principal contributeur au chrome) n'a pas donné et date de fin de vie à L'APIs

cependant, c'est à vous de décider si" certains cas " englobent les vôtres.

*BakedGoods est maintenu par rien d'autre que ce gars juste ici :)

3
répondu Kevin 2016-07-07 21:24:56

voici un tutoriel pour exporter des fichiers ZIP:

avant de commencer, il y a une bibliothèque pour enregistrer des fichiers, le nom de la Bibliothèque est fileSaver.js, tu peux trouver cette bibliothèque ici. Commençons, maintenant, inclure les bibliothèques nécessaires:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.4/jszip.min.js"  type="text/javascript"></script>
<script type="text/javascript" src="https://fastcdn.org/FileSaver.js/1.1.20151003/FileSaver.js" ></script>

maintenant, copiez ce code et ce code va télécharger un fichier zip avec un fichier hello.txt ayant contenu Bonjour tout le Monde. Si tout fonctionne bien, ça téléchargera un fichier.

<script type="text/javascript">
    var zip = new JSZip();
    zip.file("Hello.txt", "Hello World\n");
    zip.generateAsync({type:"blob"})
    .then(function(content) {
        // see FileSaver.js
        saveAs(content, "file.zip");
    });
</script>

ceci téléchargera un fichier appelé file.zip. Vous pouvez lire plus ici: http://www.wapgee.com/story/248/guide-to-create-zip-files-using-javascript-by-using-jszip-library

0
répondu Ilyas karim 2017-09-30 09:46:41