Search code examples
elixirphoenix-frameworkstatic-files

Is there a way to serve uploaded files back to the user?


Is there a way to display images sent by users in a rendered page? I've read this page about file uploads, but the only way to send it back the user is using send_file/5 which doesn't seem suitable for images to render in web page. I was thinking moving the file to the assets/static folder, but I don't feel like this is where it belongs.

I am coming from the Django world, and there was a separation between static files, and uploaded content and I was wondering and there was a similar concept in phoenix.

So in short, how can I render an image uploaded by a user?


Solution

  • There are two options here. You can base64 the image and use an inline data uri (https://en.wikipedia.org/wiki/Data_URI_scheme) directly in your view. This inflates your image size by quite a bit, and is best only for small images where the cost of an additional round-trip to the server is more than the cost of sending the 33% increased inflation in size. You also get no caching benefits at all, and repeated use of the image will result in multiple copies.

    The better option is to create a new route and action in your controller for displaying the image. You need to emit a proper content-type header for your specific image type (such as image/png), and then you should use send_file/5. You would use an <img> tag with the route for the image as the src attribute. You get a huge advantage here, and can tune all the caching to your heart's delight.

    There are some other options, such as nginx's X-Accel functionality (https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/), where you would emit the headers given in that documentation, and nginx will send the file appropriately. You would still need a dedicated route, and you would emit the headers from that routed URL.

    I wouldn't worry too much about overhead. The erlang VM is quite good at managing IO.