Search code examples
javascriptgoogle-chrome-extensionstringifyencodeuricomponent

extension crash on exporting stringified/encodeURIComponent data to file


It is about exporting extension data from options page.
I have array of objects, with stored page screenshots encoded in base64, and some other minor obj properties. I'm trying to export them with this code:

exp.onclick = expData;

function expData() {
    chrome.storage.local.get('extData', function (result) {
        var dataToSave = result.extData;
        var strSt = JSON.stringify(dataToSave);
        downloadFn('extData.txt', strSt);
    }); 
}

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

}

On button click, get data from storage, stringify it, create fake link, set attributes and click it.
Code works fine if resulting file is under ~1.7 MB, but everything above that produce option page to crash and extension gets disabled.
I can console.log(strSt) after JSON.stringify and everything works fine no matter of the size, if I don't pass it to download function..
Is there anything I can do to fix the code and avoid crash?...or is there any limitation is size when using this methods?


Solution

  • I solved this, as Xan suggested, switching to chrome.downloads (it's extra permission, but works fine)
    What I did is just replacing code in downloadFN function, it's cleaner that way

    function downloadFn(filename, text) {
        var eucTxt = encodeURIComponent(text);
        chrome.downloads.download({'url': 'data:text/plain;charset=utf-8,'+eucTxt, 'saveAs': false, 'filename': filename});
    
    }
    

    note that using URL.createObjectURL(new Blob([ text ])) also produce same crashing of extension

    EDIT: as @dandavis pointed (and RobW confirmed), converting to Blob also works
    (I had messed code that was producing crash)
    This is a better way of saving data locally, because on browser internal downloads page, dataURL downloads can clutter page and if file is too big (long URL), it crashes browser. They are presented as actual URLs (which is raw saved data) while blob downloads are only with id

    function downloadFn(filename, text) {
        var vLink = document.createElement('a'),
        vBlob = new Blob([text], {type: "octet/stream"}),
        vUrl = window.URL.createObjectURL(vBlob);
        vLink.setAttribute('href', vUrl);
        vLink.setAttribute('download', filename);
        vLink.click();
    }