Return json and binary data in Phoenix via ajax

I send an ajax request and I want to return json which contains binary data in its body. On a client I assemble it as Blob and a client downloads it. I can’t return a link to fine for some reason.

  1. Is it possible to embed binary data into an ajax json response?
    Something like

json(conn, %{data: %{title: "some title", file_content: File.read!(some_path)}})

I’ve tried and got an exception but I couldn’t trace the source, thus it might’ve not been related to this.

  1. If it’s impossible to combine json and binary data in it, how to can I return binary data? Should it be purely a binary response “xhr.responseType=blob”, that is, not json?

You can encode the binary data into string using Base64 encoding.

Keep in mind that this will increase the transfer size significantly, and base64-encoded string will have to be de-serialized on the other end.

In which case?

Do note, you say json, json only defines a few specific types:

  • JSON Value: Any of the below:
    • number: A traditionally double-sized floating point number
    • string: A unicode string
    • array: A list of JSON Value’s
    • Object: An unordered mapping from a string to a JSON Value

And so forth. Binary is not one of the JSON types, therefor you either need to make sure you file data is one of the existing types (like a unicode string) and send it as that, or you need to encode it somehow, such as by BASE64’ing it as @hubertlepicki stated above. Encoding data can of course increase the size as well (though not always, but Base64 definitely will if you use it as it can work with any binary).

1 Like

yes, how about #2?

You can just send the file as normal via send_file/3. :slight_smile:
That call is highly optimized so the OS kernel reads the file and sends to the socket as efficiently as possible. :slight_smile:

you can’t “send_file” via ajax.

From phoenix, sure you can, no issues there, all depends on the client you are using.

If the client you are using is something like jQuery’s ajax calls like post or something to javascript, well javascript can get a bytebuffer or some other form of low level array and you can work with it that way, however you will not be able to write it to a file since javascript cannot write out files on the local computer for security reasons in browsers, however any other API in any other language/platform could do it with relative ease.

All that client stuff has nothing to do with phoenix though, phoenix is happy to send along a file no problem at all. ^.^

1 Like