How to render images from database using Flask backend and JavaScript frontend

I’m working on a web app where I need to fetch image data from my database (stored as BLOB) and display it on the webpage. I can see the image data in the browser’s developer tools but it’s not showing up on the actual page.

My current setup includes a form where users enter an ID, JavaScript handles the request, and the backend returns the image. Here’s my implementation:

<!DOCTYPE html>
<html>
<head>
    <title>Image Viewer</title>
</head>
<body>
    <h2>Load Image</h2>
    <form id="imageForm">
        <label>Enter Image ID:</label>
        <input type="text" id="img_id" name="img_id">
        <br><br>
        <img id="display_image" src="" alt="Image will appear here">
        <br><br>
        <button type="submit">Load Image</button>
    </form>
    
    <script>
        document.getElementById('imageForm').addEventListener('submit', function(e) {
            e.preventDefault();
            
            var imageId = document.getElementById('img_id').value;
            var request = new XMLHttpRequest();
            
            request.open('POST', '/loadImage');
            request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            
            request.onload = function() {
                if (request.status === 200) {
                    var imageData = request.response;
                    document.getElementById('display_image').src = imageData;
                }
            };
            
            var params = new URLSearchParams();
            params.append('img_id', imageId);
            request.send(params);
        });
    </script>
</body>
</html>

On the Flask side, I’m returning the image like this:

return Response(blob_data, mimetype='image/png')

The image data appears in the network tab but doesn’t render. What am I missing here?

You’re handling the response data wrong. XMLHttpRequest treats your binary image data as text by default, which breaks everything. Set request.responseType = 'blob' before sending the request. Then use URL.createObjectURL(request.response) to create a temporary URL from the blob. This gives you a URL that points to the blob data in memory - just assign it to your img element’s src. Don’t forget error handling for when the image ID doesn’t exist in your database.

hmm, are you sure your flask route is actually returning the right mimetype? sometimes the issue isnt just the frontend - what format are your images stored as in the database? also curious, does your browser console show any errors when you try to load the image?

Yeah, you’re not setting the response type right. Add request.responseType = 'arraybuffer' before sending, then convert to base64 with btoa(String.fromCharCode(...new Uint8Array(request.response))) and set src to data:image/png;base64,${base64data}. Works every time for blob images from the database.