Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

WebGL - Saving a file in the browser

Discussion in 'Web' started by unisip, Nov 29, 2017.

  1. unisip

    unisip

    Joined:
    Sep 15, 2010
    Posts:
    340
    Hi,

    I am trying to save a file in the browser from a Unity WebGL app.
    I have a byte[] object in C# and I need to pass it to a javascript function that handles the save for me.
    I looked online and found FileSaver.js with seems to do just what I need (https://github.com/eligrey/FileSaver.js).

    So I added this function to my javascript.jslib in the Unity project:
    SaveFile: function (data) {
    window.alert("try save file");
    var blob = new Blob(data, {type: "application/octet-stream"});
    var fileName = "myTestFile.data";
    saveAs(blob, fileName);
    }

    In Unity, I have a C# class that imports this function:
    [DllImport("__Internal")]
    private static extern void SaveFile(byte[] data);

    And then I simply call SaveFile with a byte[] object to try to save it.

    I get the following error in the browser:
    Uncaught TypeError: Failed to construct 'Blob': The provided value cannot be converted to a sequence.

    I guess I am doing something wrong with the data type. It's likely that the byte[] object can't just be passed like that.

    Has anyone tried this before ?
    Any help is greatly appreciated !
     
  2. unisip

    unisip

    Joined:
    Sep 15, 2010
    Posts:
    340
    ok it looks like I found the issue. The javascript function should be:
    SaveFile: function (data) {
    window.alert("try save file");
    var blob = new Blob([data], {type: "application/octet-stream"});
    var fileName = "myTestFile.data";
    saveAs(blob, fileName);
    }

    Subtle difference, the presence of [] around data in the blob constructor
     
    QinmingRen likes this.
  3. unisip

    unisip

    Joined:
    Sep 15, 2010
    Posts:
    340
    Well, bad luck, that's still not working. I get no error but the data in the file is definitely not the data in my C# byte[].
    So the question is still opened...
     
  4. sumpfkraut

    sumpfkraut

    Joined:
    Jan 18, 2013
    Posts:
    242
  5. GrumpkinGames

    GrumpkinGames

    Joined:
    Mar 3, 2016
    Posts:
    9
    unisip - did you ever get this working?
     
  6. unisip

    unisip

    Joined:
    Sep 15, 2010
    Posts:
    340
    Yeah I found a way to send a byte array zip to the webpage and have it saved. Here is the jslib i used:
    mergeInto(LibraryManager.library, {
    ZipDownloader: function(str, fn)
    {
    var msg = Pointer_stringify(str);
    var fname = Pointer_stringify(fn);
    var contentType = 'application/octet-stream';

    function fixBinary (bin)
    {
    var length = bin.length;
    var buf = new ArrayBuffer(length);
    var arr = new Uint8Array(buf);
    for (var i = 0; i < length; i++)
    {
    arr = bin.charCodeAt(i);
    }
    return buf;
    }
    var binary = fixBinary(atob(msg));
    var data = new Blob([binary], {type: contentType});
    var link = document.createElement('a');
    link.download = fname;
    link.innerHTML = 'DownloadFile';
    link.setAttribute('id', 'ImageDownloaderLink');
    if(window.webkitURL != null)
    {
    link.href = window.webkitURL.createObjectURL(data);
    }
    else
    {
    link.href = window.URL.createObjectURL(data);
    link.onclick = function()
    {
    var child = document.getElementById('ImageDownloaderLink');
    child.parentNode.removeChild(child);
    };
    link.style.display = 'none';
    document.body.appendChild(link);
    }
    link.click();
    }
    });

    Hope this helps.

    Unisip
    Check out our VR racing game on steam: https://store.steampowered.com/app/668430/VRacer_Hoverbike/
     
    motorage likes this.