0

I cannot (afaik) create a file in my (javascript browser) client, so I want my server to do it before sending it back to the client which in turn should open a dialogue asking the user where to save the file.

How do I achieve this? Se below for a gist of what I currently have.

Client

$.ajax({
        type: 'POST',
        dataType: 'json',
        url: "http://localhost:5000/api/file",
        data: postData,
        contentType : 'application/json',
        success: function (responseData, textStatus, jqXHR) {
            // What do I put here?
        },
        error: function (jqXHR, textStatus, errorThrown) {
            alert(errorThrown);
        }
    });

Server

router.post('/file', function (request, response) {
        var content = '';
        request.on('data', function (data) {
            content += data;
        });

        request.on('end', function () {
            var contentAsJson = JSON.parse(content);
            response.set("Content-Type", "text/plain");
            response.set("Content-Length", contentAsJson.text.length);
            response.set("Content-Disposition", 'attachment; filename='filename.txt');
            response.send(contentAsJson.text);
        });
    });
MdaG
  • 2,680
  • 2
  • 34
  • 46
  • possible duplicate of [How to download a file on clicking the name of file using PHP?](http://stackoverflow.com/questions/4518702/how-to-download-a-file-on-clicking-the-name-of-file-using-php) – Krystian Laskowski Jun 07 '15 at 11:04
  • What problems are you running into? Does it return the wrong data? Does it throw an error of some kind? – Karl-Johan Sjögren Jun 07 '15 at 11:09
  • I get the data returned as expected. It's the make client store it as file via dialogue that I ponder. However @orcaman just showed me that I don't need to send this to my server at all. <=IE9 support isn't an issue in this case so this will do. – MdaG Jun 07 '15 at 11:25
  • I would however still be interested in the "correct"(?) way to do this? I assume that @orcaman answer is a hack as I'm under the assumption that javascript clients aren't suppose to be able to create and save files due to security reasons. – MdaG Jun 07 '15 at 11:31
  • @MdaG not a hack. Works on all "normal" browsers. The only unsupported bit is the blob object, which was introduced only a couple of years ago. – orcaman Jun 07 '15 at 11:46

1 Answers1

1

You can in fact generate the binary stream of the file on the client using only JS, you do not have to post the data to the server.

First, create a binary representation of your data:

var str = <<your data as string>>
var uint = new Uint8Array(str.length);
for (var i = 0, j = str.length; i < j; ++i) {
    uint[i] = str.charCodeAt(i);
}

Then, request to save this as a file:

var sampleBytes = <<your typed array with the data>>;

var saveByteArray = (function () {
    var a = document.createElement("a");
    document.body.appendChild(a);
    a.style = "display: none";
    return function (data, name) {
        var blob = new Blob(data, {type: "octet/stream"}),
            url = window.URL.createObjectURL(blob);
        a.href = url;
        a.download = name;
        a.click();
        window.URL.revokeObjectURL(url);
    };
}());

saveByteArray([sampleBytes], 'example.txt');
orcaman
  • 6,263
  • 8
  • 54
  • 69