Browsers don't (yet) support JSON serialization of forms, so AFAIK it's not really possible to send JSON to backend using pure forms.
I have two solutions that will not require saving file on the server:
1) Simple solution would be to generate an invisible form with JavaScript, create hidden input of name json
and populate it with JSON content to send to the server. On the server side, you would read the form data and parse JSON that is stored in the data. Then you just generate the file and send the file in response. The browser should trigger download dialog.
var form = document.createElement('form');
form.method = 'post';
form.action = 'url';
var input = document.createElement('input');
input.type = 'hidden';
textarea.name = 'json';
textarea.value = JSON.stringify(your_json);
form.appendChild(input);
document.body.appendChild(form);
form.submit();
form.parentNode.removeChild(form);
2) Second option uses ajax to send data to the server. The browsers need to support several APIs, though.
You do your JSON request as usual and the server should respond with header Content-Type: here-the-MIME-type-of-your-file
and with the file contents in response body.
The code on client side should look like:
var json = JSON.stringify({here: ['your', 'json', 'to', 'send', 'to', 'server']});
var xhr = new XMLHttpRequest();
xhr.open('POST', '/your/api/url', true);
xhr.setRequestHeader('Content-type', 'application/json');
xhr.responseType = 'arraybuffer';
xhr.addEventListener('load', function () {
var blob = new Blob([this.response], { // reading response, not responseText
type: this.getResponseHeader('Content-Type')
});
var url = URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.download = 'file_name.txt'; // set proper extension
document.body.appendChild(a); // it needs to be added to the document in order to work
a.click();
a.parentNode.removeChild(a);
});
xhr.send(json);
Also, the created URL objects should be revoked at some point, otherwise they will exist until the page reloads. But I think they cannot be revoked before the user downloads the file. So it's one task still to do with the above code.