40

I read few older thread about the same, but seen the file API changed a lot recently. My requirement is to save a json file (data is locally in indexdDB, but I need a way to back it up). Since I use indexdDB, I only target recent browsers, mainly chrome. So, it it possible to save data (json string) to client computer?

I have seen http://eligrey.com/demos/FileSaver.js/ , but is there a way to do it natively?

Thanks.

bsr
  • 57,282
  • 86
  • 216
  • 316

6 Answers6

81

You can use a Blob and the HTML5 a[download] feature to provide a JSON backup download:

var data = {a:1, b:2, c:3};
var json = JSON.stringify(data);
var blob = new Blob([json], {type: "application/json"});
var url  = URL.createObjectURL(blob);

var a = document.createElement('a');
a.download    = "backup.json";
a.href        = url;
a.textContent = "Download backup.json";

Here is a jsfiddle example: http://jsfiddle.net/potatosalad/yuM2N/

potatosalad
  • 4,819
  • 2
  • 19
  • 21
  • +1 great!! is there a way to save it through the "Save As" button. It would be ideal, if not i would go for the above. Thanks. – bsr May 02 '13 at 10:20
  • 1
    You may want to look into something like [Downloadify](https://github.com/dcneiner/Downloadify). From what I can tell currently, there is no plain javascript cross-browser way to force the "Save As" dialog to display. See http://stackoverflow.com/questions/2897619/using-html5-javascript-to-generate-and-save-a-file for more information. – potatosalad May 02 '13 at 15:23
  • @potatosalad: And IMHO for good reason. I worked hard to configure my browser for its download behavior. Wouldn't have Javascript tamper with that! Cool solution btw. Thank you. – Markus-Hermann May 27 '20 at 20:28
6

Yes, you can. This assumes that you have the json in text:

var toDownload=new Blob([text],{type:'x-whatever/x-backup'});
var link=window.URL.createObjectURL(toDownload);
window.location=link;

that is untested, but it should work.

markasoftware
  • 12,292
  • 8
  • 41
  • 69
  • this almost works but won't allow me to save the contents in the new window this outputs too... I can only select the outputted content, copy and paste elsewhere, any idea how I can actually save the output? – skplunkerin Jun 28 '16 at 02:03
6

You can use FileSaver.js.

Sample code:

//include the js file in html.
<script src="FileSaver.min.js"></script>    

// other code ...

//use it here.
var myjson= "{a:3, b:4}";
var blob = new Blob([myjson], {type: "application/json"});

var saveAs = window.saveAs;
saveAs(blob, "my_outfile.json");

Use JSON.stringify to create a string from JSON.

Fiddle: https://jsfiddle.net/9w9ofec4/3/

Samuel Bushi
  • 341
  • 3
  • 16
  • 1
    This answer doesn't answer the question... Description of question states that he has seen FileSaver but wants a native solution. Sorry bro – skplunkerin Jun 28 '16 at 01:52
  • 4
    The FileSaver solution actually uses HTML5 api when available, and for older browser it just works fine, which is better than using plain HTML5. So, probably one should say, that yes of course there is code for that, but why to bother, when the code will fail in many browsers, so better use the good library. – Igor Lino Oct 27 '16 at 13:38
3

based on potatosalad answer i experimented with an 'self' updating link:
jsfiddle

function saveAsFile(link, content, filename) {
    var blob = new Blob([content], {type: "text/text"});
    var url  = URL.createObjectURL(blob);

    // update link to new 'url'
    link.download    = filename + ".txt";
    link.href        = url;
}

saveAsFile(this, "YourContent", "HelloWorldFile");

the function saveAsFile() needs the calling a element as first argument.
than it updates the href target to the new blob.

Community
  • 1
  • 1
1

function saveAsJSON(data, name=Date.now()+'.json') {
  const a = document.createElement('a')
  a.download = name
  a.href = URL.createObjectURL(new Blob([JSON.stringify(data)], {type: 'application/json'}))
  a.click()
}

// https://stackoverflow.com/questions/62371219/chrome-stops-download-files-from-stackoverflow-snippets
saveAsJSON(['orange', 'banana', {name: 'apple'}])
井上智文
  • 1,905
  • 17
  • 14
0

To save the file with a custom name, you can create a hidden <a> element and then click on it. This method is used by FileSaver.js.

function download(name, text){
    var toDownload=new Blob([text],
        {type:'data:application/octet-stream'});
    var link = window.URL.createObjectURL(toDownload);
    var el = document.createElement("a");
    el.href = link;
    el.download = name;
    el.click();
    window.URL.revokeObjectURL(link);
}
Thor Lancaster
  • 103
  • 1
  • 6