Using HTML5/JavaScript to generate and save a file

后端 未结 17 1721
有刺的猬
有刺的猬 2020-11-21 07:30

I\'ve been fiddling with WebGL lately, and have gotten a Collada reader working. Problem is it\'s pretty slow (Collada is a very verbose format), so I\'m going to start conv

相关标签:
17条回答
  • 2020-11-21 07:56

    As previously mentioned the File API, along with the FileWriter and FileSystem APIs can be used to store files on a client's machine from the context of a browser tab/window.

    However, there are several things pertaining to latter two APIs which you should be aware of:

    • Implementations of the APIs currently exist only in Chromium-based browsers (Chrome & Opera)
    • Both of the APIs were taken off of the W3C standards track on April 24, 2014, and as of now are proprietary
    • Removal of the (now proprietary) APIs from implementing browsers in the future is a possibility
    • A sandbox (a location on disk outside of which files can produce no effect) is used to store the files created with the APIs
    • A virtual file system (a directory structure which does not necessarily exist on disk in the same form that it does when accessed from within the browser) is used represent the files created with the APIs

    Here are simple examples of how the APIs are used, directly and indirectly, in tandem to do this:

    BakedGoods*

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

    Using the raw File, FileWriter, and FileSystem 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);
    

    Though the FileSystem and FileWriter APIs are no longer on the standards track, their use can be justified in some cases, in my opinion, because:

    • Renewed interest from the un-implementing browser vendors may place them right back on it
    • Market penetration of implementing (Chromium-based) browsers is high
    • Google (the main contributer to Chromium) has not given and end-of-life date to the APIs

    Whether "some cases" encompasses your own, however, is for you to decide.

    *BakedGoods is maintained by none other than this guy right here :)

    0 讨论(0)
  • 2020-11-21 07:57

    You can use localStorage. This is the Html5 equivalent of cookies. It appears to work on Chrome and Firefox BUT on Firefox, I needed to upload it to a server. That is, testing directly on my home computer didn't work.

    I'm working up HTML5 examples. Go to http://faculty.purchase.edu/jeanine.meyer/html5/html5explain.html and scroll to the maze one. The information to re-build the maze is stored using localStorage.

    I came to this article looking for HTML5 JavaScript for loading and working with xml files. Is it the same as older html and JavaScript????

    0 讨论(0)
  • 2020-11-21 07:58

    This thread was invaluable to figure out how to generate a binary file and prompt to download the named file, all in client code without a server.

    First step for me was generating the binary blob from data that I was saving. There's plenty of samples for doing this for a single binary type, in my case I have a binary format with multiple types which you can pass as an array to create the blob.

    saveAnimation: function() {
    
        var device = this.Device;
        var maxRow = ChromaAnimation.getMaxRow(device);
        var maxColumn = ChromaAnimation.getMaxColumn(device);
        var frames = this.Frames;
        var frameCount = frames.length;
    
        var writeArrays = [];
    
    
        var writeArray = new Uint32Array(1);
        var version = 1;
        writeArray[0] = version;
        writeArrays.push(writeArray.buffer);
        //console.log('version:', version);
    
    
        var writeArray = new Uint8Array(1);
        var deviceType = this.DeviceType;
        writeArray[0] = deviceType;
        writeArrays.push(writeArray.buffer);
        //console.log('deviceType:', deviceType);
    
    
        var writeArray = new Uint8Array(1);
        writeArray[0] = device;
        writeArrays.push(writeArray.buffer);
        //console.log('device:', device);
    
    
        var writeArray = new Uint32Array(1);
        writeArray[0] = frameCount;
        writeArrays.push(writeArray.buffer);
        //console.log('frameCount:', frameCount);
    
        for (var index = 0; index < frameCount; ++index) {
    
          var frame = frames[index];
    
          var writeArray = new Float32Array(1);
          var duration = frame.Duration;
          if (duration < 0.033) {
            duration = 0.033;
          }
          writeArray[0] = duration;
          writeArrays.push(writeArray.buffer);
    
          //console.log('Frame', index, 'duration', duration);
    
          var writeArray = new Uint32Array(maxRow * maxColumn);
          for (var i = 0; i < maxRow; ++i) {
            for (var j = 0; j < maxColumn; ++j) {
              var color = frame.Colors[i][j];
              writeArray[i * maxColumn + j] = color;
            }
          }
          writeArrays.push(writeArray.buffer);
        }
    
        var blob = new Blob(writeArrays, {type: 'application/octet-stream'});
    
        return blob;
    }
    

    The next step is to get the browser to prompt the user to download this blob with a predefined name.

    All I needed was a named link I added in the HTML5 that I could reuse to rename the initial filename. I kept it hidden since the link doesn't need display.

    <a id="lnkDownload" style="display: none" download="client.chroma" href="" target="_blank"></a>
    

    The last step is to prompt the user to download the file.

    var data = animation.saveAnimation();
    var uriContent = URL.createObjectURL(data);
    var lnkDownload = document.getElementById('lnkDownload');
    lnkDownload.download = 'theDefaultFileName.extension';
    lnkDownload.href = uriContent;
    lnkDownload.click();
    
    0 讨论(0)
  • 2020-11-21 08:01

    OK, creating a data:URI definitely does the trick for me, thanks to Matthew and Dennkster pointing that option out! Here is basically how I do it:

    1) get all the content into a string called "content" (e.g. by creating it there initially or by reading innerHTML of the tag of an already built page).

    2) Build the data URI:

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

    There will be length limitations depending on browser type etc., but e.g. Firefox 3.6.12 works until at least 256k. Encoding in Base64 instead using encodeURIComponent might make things more efficient, but for me that was ok.

    3) open a new window and "redirect" it to this URI prompts for a download location of my JavaScript generated page:

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

    That's it.

    0 讨论(0)
  • 2020-11-21 08:02
    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();
    }
    
    0 讨论(0)
  • 2020-11-21 08:03

    Simple Solution!

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

    Works in all Modern browsers.

    0 讨论(0)
提交回复
热议问题