28

I have a JSON object in javascript. I want to simply write the JSON object to a text file. From the things that I came across so far indicate that it is not possible to do so because of security concerns on the client side. Is there a workaround?. Will it be possible to modify a file already present if put some dummy values initially?

Thanks

kosta
  • 4,302
  • 10
  • 50
  • 104

2 Answers2

35

One thing you can do is setup the JSON as a download on the fly.

var data = "{name: 'Bob', occupation: 'Plumber'}";
var url = 'data:text/json;charset=utf8,' + encodeURIComponent(data);
window.open(url, '_blank');
window.focus();

Working demo: http://jsfiddle.net/sLq3F/

Apart from that, you can't write a JSON to a file on the clientside due to security reasons. (Otherwise you have access to the filesystems of your website's users.) You would have to use a server-side language for this, and store the file on the server-side.


Correction: Looks like you can write to a file, i.e., a "sandboxed section" of the user's filesystem. See Kevin Jantzer's comment below.

Another Correction: Sorry, the Filesystem API isn't in use. From the HTMl5Rocks website: "In April 2014, it was announced on public-webapps that the Filesystem API spec is deprecated. Other browsers have showed little interest in implementing it."

ktm5124
  • 11,861
  • 21
  • 74
  • 119
  • 2
    Although, you can write to a file by using HTML5's new [FileSystem APIs](http://www.html5rocks.com/en/tutorials/file/filesystem/#toc-file-writing) – Kevin Jantzer Feb 26 '14 at 23:27
  • 2
    From @KevinJantzer 's link: "In April 2014, it was announced on public-webapps that the Filesystem API spec should be considered dead. Other browsers have showed little interest in implementing it." – stonefruit Jul 27 '14 at 16:34
  • Sorry, filesystem API isn't dependable. From the HTMl5Rocks website: "In April 2014, it was announced on public-webapps that the Filesystem API spec should be considered dead. Other browsers have showed little interest in implementing it." – Yangshun Tay Sep 28 '14 at 07:42
  • 1
    this method is failing with "complex" jsons, like `{a:{1,2,3}, b:"33", c:{1,"a"}}` but if `encodeURIComponent` is **replaced** by `JSON.stringify`, then the result is ok. – Miguel Vazq Nov 03 '15 at 12:07
  • 1
    @MiguelVazq The thing to notice in @ktm5124's example is that `data` is a string, not a raw object. You *can* just use `JSON.stringify()`, but that will give you a URL containing the raw JSON string, which can potentially cause issues if the object contains a URL (or really any string with slashes in it). The most robust method if you're starting with a raw object is to `stringify()` it *and* use `encodeURIComponent()`, e.g.: `var url = 'data:text/json;charset=utf8,' + encodeURIComponent(JSON.stringify(data));` – Ken Bellows Feb 24 '16 at 13:12
0

Perhaps this solution is a little more elegant, tested in Chrome, FF and ie7 to ie10, tested with text, JSON, PDF and XLS data (using the appropriate content type)

Either supply the saveFile() function with a data blob, or create a data blob on the fly with type set to nothing and your data between the []'s

In this example, we'll just stringify the settings object, and set the datatype correctly.

settings = { any_kind_of_object: true };
json_str = JSON.stringify(settings);

saveFile('yourfilename.json', "data:application/json", new Blob([json_str],{type:""}));

function saveFile (name, type, data) {
    if (data != null && navigator.msSaveBlob)
        return navigator.msSaveBlob(new Blob([data], { type: type }), name);

    var a = $("<a style='display: none;'/>");
    var url = window.URL.createObjectURL(new Blob([data], {type: type}));
    a.attr("href", url);
    a.attr("download", name);
    $("body").append(a);
    a[0].click();
    setTimeout(function(){  // fixes firefox html removal bug
        window.URL.revokeObjectURL(url);
        a.remove();
    }, 500);  
}
ChrisAdmin
  • 982
  • 1
  • 12
  • 32